text:
Arduino to arduino serial communication without a library
So I'm trying to send an array from one arduino to another through serial communication, without using the software serial library. The arduinos are wired rx->tx, tx->rx and ground to ground. I have a struct which holds the array of data and 2 test characters. The entire struct is then sent 1 char at a time. The receiver then receives 1 char at a time, re-calculates the test chars and if the xor of the sent and calculated tests chars is 1 then we assume an error exists and turn on a red LED. If no error exists then we turn on a green LED. I'm having some issues with my code however. It never sends any data to the 2nd arduino. Can anyone see any reason why?
Sender:
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>

#define F_CPU 16000000L
#define BAUD_RATE 9600
#define MYUBRR (F_CPU / 16 / BAUD_RATE) - 1
#define END_OF_MESSAGE 47
#define END_OF_SECTION 35
#define START_OF_MESSAGE 2
#define _BV(bit) (1<<(bit))

struct packet{
    /*Packet to send a part of the message. */
    char *data;
    char vert_check;
    char horz_check;
};

void serialInit()
{
    UBRR0H = (char) (MYUBRR>>8);
    UBRR0L = (char) MYUBRR;
    UCSR0C = (3 << UCSZ00);
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
}

unsigned char serialCheckTx()
{
    return(UCSR0A & _BV(UDRE0));
}

void serial_send(unsigned char DataOut)
{
    while(serialCheckTx() == 0){;}
    UDR0 = DataOut;
}

int isOddParity(unsigned char myChar) {
    int parity = 0;
    for (myChar &= ~0x80;  myChar != 0;  myChar >>= 1) {
        parity ^= (myChar & 1);   // Toggle parity on each '1' bit.
    }
    return parity;
}

int main(void)
{
    serialInit();
    char hozcheck, vertcheck;
    /* Add message to array below to send
     * Initialised to toets.
     */
    char *s = {'T', 'o', 'e', 't', 's'};
    struct packet sendpacket;
    sendpacket.data = s;
    hozcheck = 0;
    for(int i=0; i<strlen(s); i++){
        hozcheck += s[i];
    }
    vertcheck = (isOddParity(s[0]) + '0');

    sendpacket.horz_check = hozcheck;
    sendpacket.vert_check = vertcheck;

    serial_send(START_OF_MESSAGE);
    serial_send(sendpacket.horz_check);
    serial_send(END_OF_SECTION);
    serial_send(sendpacket.vert_check);
    serial_send(END_OF_SECTION);
    for(int j=0; j<strlen(s); j++){
        serial_send(s[j]);
    }
    serial_send(END_OF_MESSAGE);
}

Receiver:
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>

#define END_OF_MESSAGE 47
#define START_OF_MESSAGE 2
#define F_CPU 20000000L
#define BAUD_RATE 9600
#define MYUBRR (F_CPU / 16 / BAUD_RATE) - 1
#define _BV(bit) (1<<(bit))
#define START_OF_MESSAGE 2
#define END_OF_MESSAGE 47
#define END_OF_SECTION 35

struct packet{
    char *data;
    char vert_check;
    char horz_check;
};

void serialInit()
{
    UBRR0H = (char) (MYUBRR>>8);
    UBRR0L = (unsigned) MYUBRR;
    UCSR0C = (3 << UCSZ00);
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
}

unsigned char serialCheckRx()
{
    return(UCSR0A & _BV(RXC0));
}

unsigned char serialReceive()
{
    while (serialCheckRx() == 0){;}
    return UDR0;
}

void *array_concat(char *a, int an, char b){
    int s = sizeof(char);
    char *p = malloc(s * (an + 1));
    memcpy(p, a, an*s);
    memcpy(p + an*s, b, s);
    return p;
}

int isOddParity(unsigned char myChar) {
    int parity = 0;

    for (myChar &= ~0x80;  myChar != 0;  myChar >>= 1) {
        parity ^= (myChar & 1);   // Toggle parity on each '1' bit.
    }
    return parity;
}

int main(void)
{
    DDRB = 0b111111;
    serialInit();
    char tmp = 0, recvert = 0, rechoz = 0, *s, testhoz, testvert;
    int testbit = 0;
    /*to rebuild our packages*/
    struct packet packet1;
wait:
    while((tmp = serialReceive()) != 2){
        goto wait;
    }

    while((tmp = serialReceive()) != 35){
        /*Should be a single char for horizontal*/
        rechoz = tmp;
    }
    while((tmp = serialReceive()) != 35){
        /*Should be a single char for "vert" parity*/
        recvert = tmp;
    }
    while((tmp = serialReceive()) != 47){
        /*While input is not end of message grow s*/
        s = array_concat(s, strlen(s), tmp);
    }

    packet1.data = s;
    packet1.vert_check = recvert;
    packet1.horz_check = rechoz;
    testhoz = 0;
    for(int i=0; i<strlen(s); i++){
        testhoz += s[i];
    }
    testvert = ((isOddParity(s[0])) + '0');
    if((packet1.vert_check ^ testvert) == 1)
        testbit = 1;
    if((packet1.horz_check ^ testhoz) == 1)
        testbit = 1;
    if(testbit == 1){
        /*RED LED*/
        PORTB = 0b100000;
    } else {
        PORTB = 0b010000;
    }
    free(s);
}

Have you confirmed that there is definitely nothing coming out of the TX pin at all?

As far as I can tell nothing comes out. The tx led does not come on. I also tried connecting the pin to an LED and outputting an array of 0b11111111 in a continual while loop figuring it would turn it on but nothing happened.

Serial looks like it works fine. I couldn't compile your program because it didn't like the char *s = { ... } bit. It wanted char s[5] = { ... } instead.

It compiles for me in atmel studio without any errors.

And data is being transmitted fine. It is probably something wrong with your receiver code then.

In UECIDE I get "‣ scalar object 's' requires one element in initializer" - What version of GCC are you using?

In your receiver your use of dynamic memory looks to be completely broken. You start with s undefined, then allocate in your concat routine, and then assign that allocated to s. You then pass that back to concat, allocating again, copying the data, and leaving the old allocation in place. By the end of it you have allocated (and lost) loads of memory - that is if it even starts, since the first pointer you pass to copy memory from is complete junk.

GCC AVR (8bit toolchain) - 3.4.5.1061

How would I fix the memory allocation in the receiver?

See the edit to my answer.

Thanks for the answer. I'll test it tomorrow when I get chance and hopefully it will work.

In the sender, you may want to write char *s = "Toets";. Then you have a properly terminated string (the compiler adds a NULL byte at the end) that you can safely pass to strlen().

I don't understand why no one else asked WHY "without using the software serial library".

One obvious problem with the code is that s is not 0-terminated. Taking strlen of such string techically is an Undefined Behaviour, and all bets are off.
I can only speculate that it does return something larger than the max value an integer may hold (keep in mind that it returns size_t). It means that the loop
for(int i=0; i<strlen(s); i++){
    hozcheck += s[i];
}

is in fact infinite, and the program neve got a chance to send anything.

Not sure it has a bearing on your problem or not, but I can't help highlight this:
wait:
    while((tmp = serialReceive()) != 2){
        goto wait;
    }

That has to be the the most evil piece of code ever written in the history of mankind. I'm sorry, but it is.
while((tmp = serialReceive()) != 2);

is all you need. Or if you must be "pedantic":
while((tmp = serialReceive()) != 2) {
    continue;
}

There is never any call to use goto (I don't know why it was ever even included in C), and certainly not to re-run a while loop that is going to re-run itself anyway.

In your receiver you are using dynamic memory, and doing it extremely badly.
First you start out with a pointer
char *s;

Then when you receive a data character you pass that pointer to your array_concat() routine as the source for where to copy data from:
s = array_concat(s, strlen(s), tmp);

You are at that point asking it for the length of the string in an undefined pointer, which is itself undefined. It could be 0, it could be 65535, or it could be anywhere in between.
Then in array_concat you allocate memory to a pointer depending on that string length (the Uno doesn't have 65535 bytes of RAM, so anything more than the available memory will fail to allocate). And then you copy that number of bytes from the undefined source to the (possibly undefined) destination. That will then make all sorts of horrible things happen.
Then, assuming you even get that far, you return the new pointer and immediately give it to s.
Next iteration (assuming the first iteration worked) you do it all again, but now you have lost what s used to point to. That memory is gone for good. You have created a memory leak.
So you need to:

Make sure s is initialized to NULL
Do not use strlen() since you aren't working with a string but an array of data - instead maintain a count of the number of bytes received
Only do any copying of data if s actually points to some valid data (not NULL)
free() the old data pointer once you have finished copying the data (if it was pointing to real allocated memory)
Don't use memcpy to copy one byte - or if you must, then pass it the address of the byte to copy, not the byte itself - otherwise it will try and copy data from the location specified by the value of the byte, which really isn't what you want.

TBH I wouldn't use any dynamic memory at all. Instead I would stick to fixed size arrays that are big enough to hold the longest message you will send / receive. It's less fraught with danger, though it can be more wasteful of RAM.
Alternatively, if you do want to use dynamic memory, then send the length of the data with the header of your packet and allocate all the memory you need in one malloc() call before receiving all the data.

Thanks for the advice. I've just checked but it doesn't solve anything though.

I didn't think it would, since it is involved in reception not transmission.


text:
Wemos D1R2 - Onewire 2 DS18B20 passing to variable
I'm a beginer, did some tests with Uno and now have a Wemos D1R2 on my hands...
I'm building a sort of weather station that will send data to thingspeak.com and log this data there.
I managed to merge 2 examples together (1 to send data to thingspeak) and (1 to read 1 DS18B20 with onewire)
I now need to connect 2 or more DS18B20 sensors on the same Onewire BUS (I also managed to do this using this tutorial  http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#mult ), the readings come alright on serial monitor but when I try to send the readings to thingspeak a get a error:

temp_logger_multime_sensors_2:174:  error: statement cannot resolve
  address of overloaded function

Serial.print printTemperature(Probe01);
My piece of code:

/* References
    DHT11 sensor data to Thingspeak using a Wemos D1
    http://www.esp8266learning.com/dht11-sensor-data-to-thingspeak-using-a-wemos-d1.php#codesyntax_3

   Rui Santos - Complete project details at http://randomnerdtutorials.com

   YourDuino Multiple DS18B20 Temperature Sensors on 1 wire
   http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#mult
   V1.01  01/17/2013 ...based on examples from Rik Kretzinger
*/

#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// replace with your channel’s thingspeak API key and your SSID and password
String apiKey = "THINGSPEAKKEY";
const char* ssid = "WIFINAME";
const char* password = "WIFIPASSWORD";
const char* server = "api.thingspeak.com";

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS_PIN 5

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress Probe01 = { 0x28, 0xFF, 0x51, 0xA5, 0x61, 0x16, 0x03, 0x92 }; // probe 1
DeviceAddress Probe02 = { 0x28, 0xFF, 0xF8, 0x99, 0x52, 0x16, 0x04, 0xB1 }; // probe 2

WiFiClient client;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
    Serial.begin(115200);
  delay(10);

/*  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  */
  // Initialize the Temperature measurement library
  sensors.begin();

 WiFi.begin(ssid, password);

  // Connecting to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected on IP ...");
  // Printing the ESP IP address
  Serial.println(WiFi.localIP());
}

/*-----( Declare User-written Functions )-----*/
  void printTemperature(DeviceAddress deviceAddress)
  {
  float tempC = sensors.getTempC(deviceAddress);
     if (tempC == -127.00)
     {
     Serial.print("Error getting temperature  ");
     }
     else
     {
     Serial.print(tempC);
     }
  }// End printTemperature

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(1000);
  Serial.println();
  Serial.print("Number of Devices found on bus = ");
  Serial.println(sensors.getDeviceCount());
  Serial.print("Getting temperatures... ");
  Serial.println();

  // Command all devices on bus to read temperature

  sensors.requestTemperatures();

float StrProbe01 = printTemperature(Probe01); //THINK PROBLEM IS HERE
float StrProbe02 = printTemperature(Probe02); //AND HERE

  Serial.print("Probe 01 temperature is:   ");
    printTemperature(Probe01);  //<-- THIS PART WORKS
  Serial.println();

  Serial.print("Probe 02 temperature is:   ");
    printTemperature(Probe02);

  Serial.println();

if (client.connect(server,80)) {
  String postStr = apiKey;
  postStr +="&field1=";
  postStr += float(StrProbe01);
  postStr +="&field2=";
   postStr += float(StrProbe02);
  postStr += "\r\n\r\n";

  client.print("POST /update HTTP/1.1\n");
  client.print("Host: api.thingspeak.com\n");
  client.print("Connection: close\n");
  client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
  client.print("Content-Type: application/x-www-form-urlencoded\n");
  client.print("Content-Length: ");
  client.print(postStr.length());
  client.print("\n\n");
  client.print(postStr);

  Serial.print("Temperature: ");
  Serial.print printTemperature(Probe01);
  Serial.print(" degrees Celsius Humidity: ");
  Serial.print printTemperature(Probe02);
  Serial.println("Sending data to Thingspeak");
  }
  client.stop();

  Serial.println("Waiting 20 secs");
  // thingspeak needs at least a 15 sec delay be een updates
  // 20 seconds to be safe
  delay(20000);

}//--(end main loop )---

I suspect I have to transform printTemperature(Probe01); into a variable first (as you can see on the code) and use this variable on postStr += StrProbe01; as  but I tried as you can see on the code and it didnt work either.
* UPDATE * The code below works sending data to thingspeak and serial monitor fine with 1 DS18B20
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// replace with your channel’s thingspeak API key and your SSID and password
String apiKey = "THINGSPEAKKEY";
const char* ssid = "WIFINAME";
const char* password = "WIFIPASSWORD";
const char* server = "api.thingspeak.com";

const char* t2 = "5";
const char* h2 = "12.34";

//START DS18B20 Stuff
// Data wire is plugged into pin D1 on the ESP8266 12-E - GPIO 5
#define ONE_WIRE_BUS 5  // DS18B20 pin

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature DS18B20(&oneWire);
char temperatureCString[6];
char temperatureFString[6];

//END DS18B20 stuff

WiFiClient client;

void setup()
{
Serial.begin(115200);
delay(10);

// dht.begin();
DS18B20.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement

WiFi.begin(ssid, password);

// Connecting to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected on IP ...");
// Printing the ESP IP address
Serial.println(WiFi.localIP());
}

void getTemperature() {
  float tempC;
  float tempF;
  do {
    DS18B20.requestTemperatures();
    tempC = DS18B20.getTempCByIndex(0);
    dtostrf(tempC, 2, 2, temperatureCString);
    tempF = DS18B20.getTempFByIndex(0);
    dtostrf(tempF, 3, 2, temperatureFString);
    delay(100);
  } while (tempC == 85.0 || tempC == (-127.0));
}

// runs over and over again
void loop()
{

 getTemperature();

if (client.connect(server,80)) {
String postStr = apiKey;
postStr +="&field1=";
postStr += String(temperatureCString);
postStr +="&field2=";
postStr += String(temperatureFString);
postStr += "\r\n\r\n";

client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);

Serial.print("Temp in C: ");
Serial.print(temperatureCString);
Serial.print(" and Temp in F: ");
Serial.print(temperatureFString);
Serial.println("Sending data to Thingspeak");
}
client.stop();

Serial.println("Waiting 20 secs");
// thingspeak needs at least a 15 sec delay be een updates
// 20 seconds to be safe
delay(20000);
}

And this code works fine displaying 2 DS18B20 on serial monitor connected to 1 Onewire BUS, but I need to implement (uncomment) the thingspeak part now.
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// replace with your channel’s thingspeak API key and your SSID and password
String apiKey = "THINGSPEAKKEY";
const char* ssid = "WIFINAME";
const char* password = "WIFIPASSWORD";
const char* server = "api.thingspeak.com";

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS_PIN 5

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress Probe01 = { 0x28, 0xFF, 0x51, 0xA5, 0x61, 0x16, 0x03, 0x92 }; // probe 1
DeviceAddress Probe02 = { 0x28, 0xFF, 0xF8, 0x99, 0x52, 0x16, 0x04, 0xB1 }; // probe 2

WiFiClient client;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
    Serial.begin(115200);
  delay(10);

  // Initialize the Temperature measurement library
  sensors.begin();

 WiFi.begin(ssid, password);

  // Connecting to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected on IP ...");
  // Printing the ESP IP address
  Serial.println(WiFi.localIP());

}  //--(end setup )---

/*-----( Declare User-written Functions )-----*/
  void printTemp(DeviceAddress deviceAddress)
  {
  float tempC = sensors.getTempC(deviceAddress);
     if (tempC == -127.00)
     {
     Serial.print("Error getting temperature  ");
     }
     else
     {
     Serial.print(tempC);
     }
  }// End printTemp

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(1000);
  Serial.println();
  Serial.print("Number of Devices found on bus = ");
  Serial.println(sensors.getDeviceCount());
  Serial.print("Getting temperatures... ");
  Serial.println();

  // Command all devices on bus to read temperature

  sensors.requestTemperatures();

  Serial.print("Probe 01 temperature is:   ");
    printTemp(Probe01);
  Serial.println();

  Serial.print("Probe 02 temperature is:   ");
    printTemp(Probe02);

  Serial.println();

/*
if (client.connect(server,80)) {
  String postStr = apiKey;
  postStr +="&field1=";
  postStr += float(StrProbe01);
  postStr +="&field2=";
   postStr += float(StrProbe02);
  postStr += "\r\n\r\n";

  client.print("POST /update HTTP/1.1\n");
  client.print("Host: api.thingspeak.com\n");
  client.print("Connection: close\n");
  client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
  client.print("Content-Type: application/x-www-form-urlencoded\n");
  client.print("Content-Length: ");
  client.print(postStr.length());
  client.print("\n\n");
  client.print(postStr);

  Serial.print("Temperature: ");
  Serial.print printTemp(Probe01);
  Serial.print(" degrees Celsius Humidity: ");
  Serial.print printTemp(Probe02);
  Serial.println("Sending data to Thingspeak");
  }
  client.stop();

  Serial.println("Waiting 20 secs");
  // thingspeak needs at least a 15 sec delay be een updates
  // 20 seconds to be safe
  delay(20000);
 */
}//--(end main loop )---

It has all to do on generate a sort of variable (perhaps float , im not sure) and passing it as a http string
Thanks

Your question would benefit greatly from a [http://stackoverflow.com/help/mcve](minimal, complete, verifiable example) since the problem you have is with code you haven't posted.  It would also be helpful to post the version (again, minimal, complete and verifiable) which does work.

@MarkSmith sorry about that, I tried to shorten the code but get that would be hard to simulate.. here goes the whole code (I tried to clear as much as possible) the problem start ater sensors.requestTemperatures(); when I add the Thingspeak section

In the code that works, you have:
if (client.connect(server,80)) {
String postStr = apiKey;
postStr +="&field1=";
postStr += String(temperatureCString);
postStr +="&field2=";
postStr += String(temperatureFString);
postStr += "\r\n\r\n";

In the code that does not work you are doing this:
if (client.connect(server,80)) {
  String postStr = apiKey;
  postStr +="&field1=";
  postStr += float(StrProbe01);
  postStr +="&field2=";
   postStr += float(StrProbe02);
  postStr += "\r\n\r\n";

Print out the both the Strings that you are sending, postStr, using Serial.print. Compare the result. I'm not at home at the moment to try it out, but I'm sure the float(StrProbe01) and float(StrProbe02) is wrong. Thingspeak explains in their guidelines what the string that you are sending should look like.

Try returning float from printTemp:
 /*-----( Declare User-written Functions )-----*/
  float printTemp(DeviceAddress deviceAddress)
  {
  float tempC = sensors.getTempC(deviceAddress);
     if (tempC == -127.00)
     {
     Serial.print("Error getting temperature  ");
     }
     /* else
     {
     Serial.print(tempC);
     }
     */ you won't be needing this
     return tempC;
  }// End printTemp

And call it as you would in your commented example.
I suspect that it is not the most efficient way, but it should work.

Re your edit : I'd create a new project and put just the commented out code in setup (and the minimum you need to get it working) and then post the problems you have with that.
I can't see any compile problems, but the data you are sending to thingspeak doesn't look right.  I think you are sending:
String postStr = apiKey + "&field1=" + float(StrProbe01) + "&field2=" + float(StrProbe02) + "\r\n\r\n";

And I think you should be sending:
String postStr = "field1=" + float(StrProbe01) + "&field2=" + float(StrProbe02) + "\r\n\r\n";

(Based on this example Arduino.cc)

Since the DeviceInformation variables are not POD (Plain Old Data) it would be slightly more efficient to use references or pointers, this will avoid copying them around.  If you do that you could make you global variables Probe01 and Probe02 const variables.
In loop around line 98 you call printTemperature() and assign the return value to a float.  Which is very strange, because around line 72 you define void printTemperature().  So I suspect there may be a function in the Dalas library call printTemperature that returns a float and this is the overloaded function it is talking about.
So to fix it change the name of you printTemperature function and change the two lines it is called on.  Hopefully that will fix this problem.

Thanks @Matt , but like I said I am starting in the world of C and arduino, I am barelly merging samples from internet together and trying to make them work :)
I updated my post with 2 codes that I got running, 1 code read ONE temp sensor and display on serial monitor and also send to thingspeak platform
another code is able to read 2 sensors on the same bus, but I cannot manage to get this 2 readings to send over thingspeak

Possibly can use :: notation to qualify printTemperature(), ie to indicate which namespace to use.  See eg namespace and name lookup at cppreference.com

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
ESP-01 not waking correctly up after deep sleep
I have an ESP-01 that I want to measure pool temperature with. It will send the data over MQTT to the broker.
I have connected RST to GPIO16 so I can use the deep sleep functionality. Currently I am testing sending a "hello world" to the MQTT broker, and everything works fine when booting up the first time, but it seems like the ESP never wakes up correctly after the first deep sleep.
My script looks like this:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Set ADC mode
ADC_MODE(ADC_VCC);

// WiFi settings
const char* ssid = "Network";
const char* password = "Password";
IPAddress ip(192, 168, 0, 100);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

// MQTT settings
const char* mqtt_server = "192.168.0.110";
const int mqtt_port = 1883;
const char* mqtt_user = "User";
const char* mqtt_pass = "Password";
const char* mqtt_client_name = "poolsensor";
const char* mqtt_topic = "pool";

// Data wire plugged into D1 on the ESP8266 ESP-01 - GPIO 5
#define ONE_WIRE_BUS 5

// Setup OneWire instance to communicate with any device
OneWire oneWire(ONE_WIRE_BUS);

// Pass our OneWire reference to Dallas Temperature
DallasTemperature DS18B20(&oneWire);

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);

  // Annuonce connection
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // Setup WiFi config and connect
  WiFi.mode(WIFI_STA);
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're connected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");

    // Attempt to connect
    if (client.connect(mqtt_client_name, mqtt_user, mqtt_pass)) {
      // Success
      Serial.println("connected");
    } else {
      // Fail
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");

      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);

  // Start WiFi setup
  setup_wifi();

  // Set MQTT server
  client.setServer(mqtt_server, mqtt_port);

  // Set resolution to 0.25
  DS18B20.setResolution(10);

  // Start sensor
  DS18B20.begin();
}

void loop() {
  if (!client.connected()) {
    reconnect();
  } else {
    // Get temperature
    /*
    DS18B20.requestTemperatures();
    float temp = DS18B20.getTempCByIndex(0);

    if ((temp > -20) && (temp < 60)) {
      client.publish("pool/temperature", String(temp).c_str(), true);
    }
    */

    client.publish("pool/temperature", "hello world");
    Serial.println("published temperature");

    delay(1000);

    // Sleep
    ESP.deepSleep(60 * 1000000);

    delay(3000);
  }
}

Everything looks good in the serial monitor when compiling and uploading code, as the code runs the first time:
Connecting to Network
......
Connected, IP address: 192.168.0.100
Attempting MQTT connection...connected
published temperature

And I can see in my MQTT debugger that it receives hello world. After around 60 seconds, the following is shown in the serial monitor (lots of gibberish):
{l�l��|��d�|�d�b<����s�c$�#��ng�lgn���cxp��${$sd�s��'�c�ncp��

This is the last message I ever receive from the ESP, so I assume it never deep sleeps again and runs over the code again.
Anyone experienced the same, or see a bug in my code?

you have io 0 LOW?

How did you connect anything to GPIO16 on an ESP01? Other than very carefully of course - and D1??? that's wemos/nodemcu garbage (plus the  ESP01 doesn't break out gpio 5 either

if you set your serial monitor to 74880 baud, then you may be able to read the gibberish

@JaromandaX Actually the temp. sensor is not connected yet, so I commented out the code. I ran a thin copper wire from RST to the correct pin on the chip. Baud 74880 worked, and it reads the following: ets Jan  8 2013,rst cause:5, boot mode:(1,6) ets_main.c but only once, and never more.  @Juraj no, should I use pinMode(0, LOW); ?

boot mode:(1,6) look that up , I think you're in "Download code from UART" mode - should I use pinMode(0, LOW); no, or yes, doesn't make a difference

boot mode:(1,6) definitely "Download code from UART" mode - you need to make sure GPIO0 (and GPIO2 - but that doesn't seem so flakey on an ESP01) are HIGH on boot - use a pullup resistor from GPIO0 to VCC

@dandavis, he answered that " I ran a thin copper wire from RST to the correct pin on the chip"

@JaromandaX I have a similar issue - receive a lot of gibberish after coming back. Changing Baud to 74880 revealed boot mode:(3,7). Does this mean that GPIO0 and GPIO2 are high as they should, but something else is wrong? DFRobot show in their diagram that XPD is connected, which is shortcurcuited to RESET.

@JensMunk boot mode:(3,?) does indeed mean the 0 and 2 are high and 15 (MTDO) is low, as it should be for "normal" boot - so that's not your problem

Pretty sure you will need gpio 16 connected to reset in order for this to ever work, it’s tricky but not impossible. Have a read here:
https://randomnerdtutorials.com/esp8266-deep-sleep-with-arduino-ide/

I did that. Small copper wire from RST to GPIO16 on the chip.

Sorry, missed that one. From your code above it should be waking as expected. As others have said pulling GPIO 0 high is required for normal boot, GPIO 2 is not required but it is good practice to ensure stability. What you are most likely seeing and what I have seen in the past, if you have GPIO 0 grounded, i.e. to program with the arduino IDE, immediately after programming is complete, the chip will reboot normally and run with GPIO 0 grounded, but only once. If you leave GPIO 0 grounded and reboot again (or the chip wakes from sleep) it will not boot. Take GPIO 0 high and it should  work.

You left io 0 floating. With io 0 not HIGH at boot, the esp8266 goes into flashing mode.
The wake-up from deep-sleep is boot startup. So your code doesn't start if io 0 is not pulled high. Add a pull-up for io 0.
If you set Serial Monitor to 74880 baud, you will see the boot-log readable. It will print 1 as first value in "boot mode". This value is set from state of io 15, 2 and 0. 15 should be LOW and io 2 and io 0 HIGH for normal boot. 1 indicates that only 2 is HIGH.

Thanks for your reply. I'm not quite sure if I understand. No guides I've read says I have to pull 0 high. I use a programmer for programming, but I still have the same initial issue when I disconnect the programmer and just connect VCC and GND to a power source.

every good esp-01 tutorial connects EN and io 0 to VCC. I would use a pull-up resistor

do you understand that io 0 state at boot determines if the board boots to application or to bootloader?

Of course, but previously I never have to do this. I've used ESP-01 in several projects, but never with deep sleep, so this is new to me.

after upload it start without reboot

fwiw, i've found you need to wire EN to VCC on the ESP-01. but not on the ESP-01S, if that clarifies things.

yes, 01S has pull-ups on board, but then to flash it io 0 most be connected to ground

Ok, maybe I actually have an 01 and not 01S. I will do some research on this.

@Ronny-AndréBendiksen, what is the result? did the answer help?

I had the same problem and i found out, my CH_PD pin and RST pin were shorted together, when i was connecting wire from RST to GPIO_16. On the chip, the CH_PD pin is next to GPIO_16, so when you short them, the RST pin is always high, so esp cannot reboot anymore without external grounding. I fixed it and now deep sleep is working again!

Just thought I would add my findings into the No recovery from Deep sleep.
I purchased 4 Ali express ESP12E (same module as the Wemos D1) and all 4 of them failed to wake from deep sleep with known working code.
Being in a position to investigate this I first took the EMI cover off the module and did a thourough check against the Expressif data sheet for ESP8266EX.
Could not find any problems. RTC wake up pulse driving the RST pin no issues.
So I purchased some RAW ESP8266ex chips from Digikey and replaced the onboard CPU. Still no luck. The only thing it could now be was the flash memory chip or 26Mhz crystal. Check the crystal on a scope. Perfect.
Finally purchased four replacement 1Mbit flash chips from Digikey.
Bingo. Worked first time. Changed the other 3 flash chips and now they are all working.
To conclude...It appears that cheap flash chips load the serial data bus when the CPU boots from DeepSleep Wake up. It cant load the firmware and goes into "zombie mode"
pulling about 33mA current. A second reset pulse usually starts the system as the bus is already powerd up.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Send .wav file from SD card to NodeMCU via serial port
I was able to send a text file in the SD card to NodeMCU using the serial port of an Arduino Mega using this code:

if (readSerial1 == "Okay I'm ready") {
  myFile = sdf.open("uid.txt", FILE_READ);
  if (myFile) {
    while (myFile.available()) {
      char toUID = myFile.read(); //read each char and store to toUID
      uidContent += toUID; //store char to form a String
    }
    Serial1.print(uidContent);
    myFile.close();
  }
}

And it will be read by the NodeMCU then sent to another NodeMCU and stored in the SD of another Mega wirelessly using this code.
while (1) {
  if (Serial.available()) {
    uid = Serial.readString();
    break;
  }
}
data = uid.c_str();
port.beginPacket("192.168.4.255", 2390);
port.write(data);
port.endPacket();

Now, is it possible to send a wav/mp3 file using this process or is there any other way?

What is the type of uidContent, String? If so, then String is not suitable for transmitting bytes. Also your current code will not work with big files, as it requires to load all file content to SRAM (8KB on MEGA) before sending it.

uidContent is String

do have any examples?

For the Arduino part, a quick google search for "arduino read sd file by chunk" gave me this https://forum.arduino.cc/index.php?topic=357548.0 which has an example of reading and writing a file one byte at a time. Not really performant, but it has no memory problem.

For the other side (NodeMCU), I can't comment as I don't use NodeMCU. It is likely one problem you may have is to detect when the file is finished receiving.

I am now able to send the content of the wav files from Mega to NodeMcu through its serial ports, but when i would recieve it on my other nodeMcu part, some parts of the WAV header is not being sent.
Here is a sample of the content of the original wav file:
RIFF¤L  WAVEfmt      À]  À]    data€L  €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
While this is what Im recieving on the other node mcu:
RIFFäN€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
It seems to skip some of the 44byte header of the wav so I wont be able to play it on the other Mega.


text:
avrdude: ser_open(): can't set com-state for "\\.\COM2"
I have an unofficial Arduino Uno.
I've tested these:

Testing on USB 2.0 and USB 3.0
Changing Port (COM XX)
Updating drivers for the Unknown device to Arduino Uno (COM XX)
Resetting Arduino Board
Plug/Unplug
1x PC Reboot
Burning bootloader
Changing 'Programmer'
Uninstalling-Reinstalling device
Holding the "Reset" button while I Upload
Testing different examples (Blinking/Voltage Serial Read)
Testing different "Board" in Arduino software (just in case, you never know)
Removing jump wires

Does anyone have any suggestion more than I just tried?

Which version of Windows are you on?

Arduino app is 1.6.9.

I asked which version of Windows you are using, not which version of the Arduino IDE you are using.

Oh man sorry, I was not very careful. Windows 10.

And what USB chip does your unofficial Uno use?

The board is similar to that one : (Same Brand, but for example behind the USB port the component's text says "U12.000\n r4 ON" where \n is new line)
http://www.ebay.com/itm/M-J-Duino-Arduino-Uno-R3-Compatible-CH340-with-USB-and-Serial-Headers-/311393221914
I don't know how to find the USB chip you're asking sorry. Send me instructions if the information I give you are not enough.

It's the chip nearest the USB socket. In that picture it's the black rectangle next to the crystal that says "12.000"

Thanx, I edited my previous comment with a liiitle more information. I suppose now you can post an Answer now that you have information about the USB chip right ? I mean I just want to reward you :D You already made me think about the USB chip, didn't think that clones used a different one.

I don't understand what you are describing. Please take a photograph of your actual board with a closeup of the USB socket area.

The difference I was talking about : http://prntscr.com/bfhnrq
The whole board : http://prntscr.com/bfho23

That's just the crystal. I need to know what it says on the chip. The big black rectangle just above the component you are describing in that picture. The one with lots of pins sticking out of it.

It says : Header is "WCH" and the rest "CH340G \n 202685413" with \n representing a new line.

I thought that looked like one of those... So... Have you installed the CH340G drivers? Or are you trying to use the genuine Arduino Uno drivers?

Thank you kind sir. I really didn't know that they used different USB chips. And that's because ? (If you can answer ... that would be nice :D )
I installed the CH340G drivers and now it works perfectly :D
Also "Answer The Question" so I can give you some credits if you want.

After spending hours struggling with the same problem, @Brew's response solved my problem! Thanks!

The board you have uses the CH340G chip instead of an ATMega16U2 or FTDI FT232R chip.
It requires special drivers, not the ones that come with the IDE.
Why do they use that chip instead of the proper one? Simply because it's dirt cheap. They are the cheapest of the cheapest of the cheapest USB chips around. They frequently die. You might want to save up and invest in a genuine Arduino at some point, because that one may well die out of the blue.

I had the same problem with the cheap nano from Amazon Longrunner. At first, it worked, I could program it. Then, I farted around with my COM port numbers because I was tired of being in the COM14 area.
Since that moment, it stopped working. IDE couldn't find the port COM3. After reading you guys, I also noticed that the device was identified RAMPS which it wasn't before. I updated the driver which didn't work; it told me I was already with latest driver.
So I deleted that driver and reconnected my Nano and lord and behold, the new driver USB-SERIAL CH340 installed and everything was fine. El cheapo still works. I don't care to pay more just for the USB chip which I will use only once. The uP is still up to par.

I had the same problem. I was able to upload a simple Blink example, but not my own program. And I thought there's no problem in my program, since I successfully tested it on other Arduino before. But actually, that was the problem. I had this in my program (for console logs):
void setup() {
  Serial.begin(9600);
}

Then I read that different Arduinos use different baud rates. Originally I tested it on Arduino Mega, but this time I wanted to upload it to "unofficial" Arduino Nano (for which you have to use ATmega328P (Old Bootloader) option when uploading).
Since I didn't need debug logs in my program anymore, I removed these 'Serial' commands completely. Then it got uploaded without problems.
A short article on this topic

so the upload goes to the bootloader, not to your sketch and the baud rate used by the IDE should match the baud rate used by the bootloader. The baud rate set in sketch is irrelevant

Later, I got this error for this board even without 'Serial' commands in my program. So maybe there was something more happening. It took me like 20 attempts to upload it to that board again. (Other board worked without problems). So maybe it wasn't actually related :-\


text:
Need PPM out of MQ4 sensor
I'm using this working library to extract H2 & Alcohol in PPM from sensors.
UPDATE
I read the readme file and used the example shown.
But this gives me an error.
This is the code:
  //Include the library
#include <MQUnifiedsensor.h>
/************************Hardware Related Macros************************************/
#define         Board                   ("Arduino UNO")
#define         Pin                     (A4)  //Analog input 4 of your arduino
/***********************Software Related Macros************************************/
#define         Type                    ("MQ-4") //MQ4
#define         Voltage_Resolution      (5)
#define         ADC_Bit_Resolution      (10) // For arduino UNO/MEGA/NANO
#define         RatioMQ4CleanAir        (4.4) //RS / R0 = 60 ppm
/*****************************Globals***********************************************/
//Declare Sensor
MQUnifiedsensor MQ4(Board, Voltage_Resolution, ADC_Bit_Resolution, Pin, Type);
// Setup
MQ4.setRegressionMethod("Exponential"); //_PPM =  a*ratio^b
MQ4.setA(1012.7); MQ4.setB(-2.786); // Configurate the ecuation values to get CH4 concentration
MQ4.setR0(3.86018237); // Value getted on calibration
// Loop
MQ4.init();
MQ4.update();
float ppmCH4 = MQ4.readSensor();

And the error:
Arduino: 1.8.13 (Mac OS X), Board: "WeMos D1 R1, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"
MQ4:17:1: error: 'MQ4' does not name a type
MQ4.setRegressionMethod("Exponential"); //_PPM =  a*ratio^b
^
MQ4:18:1: error: 'MQ4' does not name a type
MQ4.setA(1012.7); MQ4.setB(-2.786); // Configurate the ecuation values to get CH4 concentration
^
MQ4:18:19: error: 'MQ4' does not name a type
MQ4.setA(1012.7); MQ4.setB(-2.786); // Configurate the ecuation values to get CH4 concentration
^
MQ4:19:1: error: 'MQ4' does not name a type
MQ4.setR0(3.86018237); // Value getted on calibration
^
MQ4:21:1: error: 'MQ4' does not name a type
MQ4.init();
^
MQ4:22:1: error: 'MQ4' does not name a type
MQ4.update();
^
exit status 1
'MQ4' does not name a type

please describe the I tried several things

You understand that if the library doesn't do what you need, you can make your own copy of it and modify it, right?

The function serialDebug() is only for debug, as the name says. When you need a specific value, the  library also provides functions for that. Have you ever tried looking at the readme of the library. There you can find the line float ppmCH4 = MQ4.readSensor(). Seems to be what you want

@chrisl I looked and used the example from the readme but it gives me the error I wrote in the updated question.

You need to write a real code with the functions setup() and loop(). It isn't enough to write a comment with these names. You cannot execute any functions at global scope (outside of any other function).

@chrisl thanks for the help. But I figured out what the origin of the problem was. There where library issues reinstall of all did the trick! Thanks for the help though! :)


text:
Arduino vs Wemos Fan control
I have a working fan control with the correct wiring that works with arduino.
I would like to change the arduino with a Wemos D1 mini board.
When I hook everything up. The fans are not activated.
The fan is driven by a 12v charger. And the irf540n cicruit powers that. They just share a common ground and the pwm pin D5
Is there something I need to know about the difference in both of them?
Below is the code, I've changed D5 in the code to 14.
Still nothing seems to work.
    #define fan D5

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("start");
  pinMode(fan, OUTPUT);

  digitalWrite(fan, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(1000);
  digitalWrite(fan, HIGH);

  delay(1000);
  digitalWrite(fan, LOW);
}

Yes. The Wemos is 3.3V. Have you taken that into account with your circuit design?

What kind of Arduino did you use before? Arduino is a broad family of different boards with different chips

@Majenko I thought that didn't matter because the fan is driven by a 12v charger. And the irf540n cicruit powers that. They just share a common ground and the pwm pin D5

IRF540 is not a good choice. You want something that has a lower threshold voltage really.

Indeed just switched everything up with an Arduino and it works... @Majenko would a level bit shifter work for this? (pure out of interest)

The IRF540 is not suitable to be controlled by a 3.3V device because it has a gate-source-threshold voltage of 2-4V (that's the voltage at which the mosfet starts to conduct, but you need to be above that voltage). While this worked at 5V logic level on the arduino, the 3.3V are not enough to make the mosfet switch entirely.
A suitable mosfet has a threshold voltage below 1V. Also for a fan, you eon't need a big mosfet rated for 30A, a tiny one will do it.


text:
Encoding clock signal into linear block codes
In the VirtualWire library, it is possible to encode the clock signal as the library is doing with 4b/6b coding. This is possible because VirtualWire uses convolutinal coding, where the information is spread along the sequence. But, is the same possible for linear block coding, such as LDPC/Hamming?
Otherwise, if it is not possible, then how would I best deal with the signal going out of sync with serial communication, given I want to use LDPC coding.
Lastly, the reason I am using serial communication is because I will have numerous nodes in my wireless mesh network, so to my knowledge, for the sake of: speed, power efficiency, scalability, ease of implementation, etc, serial communication works best. But has anyone had better luck with any other types of communication that can take care of the sync problem, while accounting for speed, power efficiency, scalability, etc?
EDIT: The way I am doing wireless communication is by using simple rf transceivers. There will by one transceiver per node and I am trying to create a stable channel between one node to another. The communication channel isn't very reliable without some error correction. And I don't want to use the existing VirtualWire's convolutional error correction. I want to use LDPC codes, developed by Radford Neal. My goal is to first create a stable channel from one Arduino to another. Then, I will implement the network.

@Majenko Any ideas?

Are you concerned with the transmission between microcontroller and wireless radio or between nodes in the mesh? And could you elaborate on your requirement to transmit a clock signal? Wireless mesh networks normally don't need that in order to communicate.

Except of course if you intend to implement your very own protocol throughout all the OSI layers. ;)

I do actually intend to implement my very own protocol. Long road ahead. @sekdiy

Still, what part of your communication needs a self-clocked data stream (i.e. see my above question)?

Sometimes the receiver doesn't realize which bit is the start bit, and assumes one of the message bits was the start bit. The internal delay between the start bit and the message, and the internal delay between each bit of the message is different. This causes the a leakage of extra bits or loss of certain bits. Does that clarify?

Well, if you want to stream (and maybe later make your own flow control) then why not do it like in other networks before yours (like Ethernet): Manchester Code (https://en.m.wikipedia.org/wiki/Manchester_code). It's been used for that purpose before (see e.g. http://forum.arduino.cc/index.php?topic=63755.0) and there even are libraries available (e.g. from Atmel). Make sure that you have a plan at what layer you have to solve which problem, though. They can't be tackled all at the same level.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Marlin g-codes applicable for a Melzi Sanguino board
How/where do I find a complete listing of "acceptable" Marlin g-codes applicable to a Melzi Sanguino board on a 3D printer (Zonestar). It appears that not all printer boards accept all available Marlin codes.

Then I was thinking incorrectly. I had assumed that not all g-codes (from a Marlin build) were, in fact, “implemented” the same way on all boards, and some would not even be recognized or interpreted. But I still don’t understand why that is.

It depends what software is installed on the board. The board doesn't define the codes, the software does.

What exactly don't you understand? G Code is a broad standard. The developers if a firmware might think, that some G codes are not needed for the purpose, that the firmware is meant for. Thus they might decide to not implement them. Implementing all possible G codes would be a time consuming task. As much of this is open source, the developers might want to save some resources for imortant stuff

Ok, thanks for the clarification.

As already written in the comments the software defines what G-Codes are taken by a (printer) boardBUT Even if the software has the same name (eg Marlin) it might behave different on different boards because of:

different release versions for different hardware
different release repositories being ahead or behind the master repo
hardware specific features a G-code triggers (most unlikely)

The clever way is to go from features I need to software supporting thosefeatures to boards supported AND useable for my hardware to controll (3d-printer/CNC-router/laser-cutter aso)
  -


text:
Arduino IDE programs Leonardo but cannot open serial terminal
I'm using Arduino: 1.6.7 (Mac OS X 10.11.3), Board: "Arduino Leonardo".
When I try to program my code, it works without problems.
When I want to open the built-in Serial Monitor or Serial Plotter, it says "Board at /dev/cu.usbmodem1421 is not available".
The board is available and my simple code even works using "SerialTools" from Mac App Store. So there must be some problem with the Arduino IDE.
No serial related messages on dmesg. Comically it mounts and umounts my Boot OS X and Recovery HD partitions every time I unplug the Leonardo.
hfs: mounted Recovery HD on device disk0s3
hfs: unmount initiated on Recovery HD on device disk0s3 hfs: mounted
Boot OS X on device disk2s3 ioqueue_depth = 64,   ioscale = 2 hfs:
unmount initiated on Boot OS X on device disk2s3

Any ideas?

int inByte = 0;         // incoming serial byte

void setup() {

    // start serial port at 9600 bps:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

}

void loop() {

  if (Serial.available() > 0) {
    inByte = Serial.read();
    Serial.println("Hi");
  }

}

did you ever solve your problem. If so, could you post the answer here please?

Could you be affected by https://github.com/arduino/arduino/issues/3495 ?


text:
Encoders for precise robot turns
So I recently purchased:
DFRobot Wheel Encoders
DFRobot 3PA and 4WD Rovers (2pk)
Romeo V2 Arduino Controller
I was doing a bit of research online and I'm trying to figure out how to use the encoders to control the PWM applied to the motors which will make precise turns. This seems like a popular method to use. Here is some of my code. I have nothing for the encoders yet. I only have the sensors working the PWM control for the motors. All my code does is stop the motors when the front sensor detects a wall. My next step is to implement the encoders to give the robot a 90 degree turn. Does anyone have some sample code or tips on how to do this? Thanks in advanced!

  void stop(void)
    {
      digitalWrite(5,LOW);
      digitalWrite(6,LOW);

    }
    void forward(char a,char b)
    {
      analogWrite(5,a);
      digitalWrite(4,HIGH);
      analogWrite(6,b);
      digitalWrite(7,HIGH);

    }
    void back(char a,char b)
    {
      analogWrite(5,a);
      digitalWrite(4,LOW);
      analogWrite(6,b);
      digitalWrite(7,LOW);

    }
    void Left(char a,char b)
    {
      analogWrite (5,a);
      digitalWrite(4,LOW);
      analogWrite (6,b);
      digitalWrite(7,HIGH);

    }
    void Right(char a,char b)
    {
      analogWrite (5,a);
      digitalWrite(4,HIGH);
      analogWrite (6,b);
      digitalWrite(7,LOW);

    }
    void setup(void)
    {

      pinMode(buttonPin2, INPUT);
      pinMode(buttonPin3, INPUT);
      for(int i =4;i<=7;i++)
        pinMode(i, OUTPUT);
      pinMode(LED_BUILTIN, OUTPUT);
     forward(100,100);

      Serial.begin(9600);

    }
void GetSensor()
{

  Sen_Val_B = SenAvg(Sensor_Back);
  Sen_Val_F = SenAvg(Sensor_Front);
  Sen_Val_R = SenAvg(Sensor_Right);
  Sen_Val_L = SenAvg(Sensor_Left);

}

int SenAvg(int SensorNumber)
{

  Arr[100]= 0;
  avg = 0;

  for(int i = 0; i<100; i++)
  {
    Arr[i] = analogRead(SensorNumber);
    avg = avg + Arr[i];
  }
    avg = avg/100;
    return avg;
}
void loop(void)
{

   GetSensor();
  if(Sen_Val_F > 200)
  {
   stop();
  }

}

What encoders do is give you clocked feedback on motor rotation, which you can count to get an idea of position and speed. So in order to turn by a specified amount, you will need to know how much your wheel has to turn for the given angle. You can then turn the wheel precisely by dividing your wheel circumference with the maximum encoder ticks per revolution.
Say we get 600 ticks per revolution and our wheel has a circumference of 10cm.
We would then turn the wheel by 100mm / 600 = 0,16mm per encoder tick!
You could even write a function taking more parameters into account (robot diameter/distance between wheels) that calculates these values.
A faster/more empirical approach than gathering all these values is to just drive your robot for x (i.e. 100) ticks and measure the angle it drove to get a direct relation between encoder ticks and robot angle.
Another, much more precise solution would be to utilize a compass or gyroscope to measure the robot's orientation and rely on that instead of the encoders.

All my code does is stop the motors when the front sensor detects a wall. My next step is to implement the encoders to give the robot a 90 degree turn.

would this work?
  if (wall_sensed()) turn_90right(); //if wall is sensed, turn 90 degrees to the right

You may also consider change
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);

to:
  digitalWrite(MOTOR_LF,STOP);   //stop left front motor
  digitalWrite(MOTOR_LR,STOP);   //stop left right motor

so that

it is a lot more readable; and
if you were to change pin assignment, it is done consistently throughout your code.

I can get the robot to turn but I'm trying to get precise 90 degree turns. I was doing the brute force approach but just using a delay. But this method seems to be inconsistent.

Hmm, when making a turn, your wheels may slip. You could check the accuracy on a compass sensor. Because if you turn a few times, you'll slowly get an offset due the inaccuracies. With a compass you get an absolute heading instead of accumulating all turns (which accumulates the error).


text:
MKR GPS shield inconsistent GPS connection/data printing...library issue?
I have been using a MKR WiFi 1010 board with GPS shield for a very long time (year+) and have not been able to solve my problems with the GPS data dropping out.
The setup for my field application is a MKR WiFi 1010 stacked with the MKR GPS shield, the MKR ENV Shield (version1), and 2 analog sensors, with data saved to a microSD card onboard the ENV sensor and GPS data transmitted over BLE to a phone app (this was done to try to keep an eye on the GPS connection in real time).
This field application runs on battery power, so uses no serial commuincation with the laptop (i.e. no Serial Monitor). This code has run for long periods of time, collecting hours worth of data on the SD card... but this is not EVERY time. In fact, it's only about half. Other times, I use the same sketch and check the SD card to find that only the headers have printed and no data was saved. I've explored forums and taken the suggestions of removing delays and editing the library (MKR GPS Shield Sampling Frequency) but to no avail.
Now, I have gone entirely back to basics and am still left puzzled. I am using the GPSLocation example sketch that comes with the Arduino_MKRGPS library (only edit is the line that initializes the GPS in shield mode, GPS_MODE_SHIELD).
There are no delays in this sketch, and of course I have the SM open on the correct baud rate. It is supposed to just continuously print 5 parameters to the SM. I have run this sketch repeatedly in the same, unobstructed location over the last few days and this is what has happened:

Sometimes, the initial connection is quick (<30 s- 1 min). Sometimes it takes a few minutes, and sometimes I wait an extremely long time (25 mins with still no connection) at which point I give up.
Once the GPS has connected, it does not appear to stay connected in a consistent manner. I've attached a part of the SM printout with time stamps. The time between printing varies from 1s to tens of seconds, to over a minute. All with 6+ satellite connections.

Being that there are no delays in the code to regulate the frequency of printing to the SM, my thought is that the inconsistent gaps of time between printing come from either:

an unstable connection to the GPS, which I would have no clue how to solve.
Or, more likely,
something wrong with the way the GPS.available() function is structured in the library.

I have made my way into the CPP files of GPS, minmea, and SerialDDC and right now it is beyond my current programming abilities / comprehension. I will be doing some reading to understand NMEA and parsing and how the data being received by the GPS actually gets printed to the SM.
Being that time is a very precious resource and this problem is currently holding up field work for my dissertation, I am hoping you kind people may be able to help me narrow down my issue.
Just getting the GPS to print at a consistent rate to the SM is step 1. Then I can get to figuring out if this fixes my problem in my field application.
Link to the Arduino_MKRGPS library with the sketches and files I mention: https://github.com/arduino-libraries/Arduino_MKRGPS/tree/master

I've found this in the GPS.cpp file- and I'm wondering if it could be messing things up for my battery-op application bc it calls for serial print when I am not connected to a SM.
void GPSClass::poll()
{
if (_stream->available()) {
char c = _stream->read();
#ifdef GPS_DEBUG
Serial.print(c);
#endif


text:
Can I use SPI-related pins as a Digital Output?
I am trying to use an esp32 (NodeMCU-32s) as a ringlight controller for my camera. All it should do is sense when an input pin goes low (the camera's output connects to ground when the shutter goes off) which is easy to detect with a simple digitalRead(). If low, then it raises 6 pins with digitalWrite() which are connected to transistors which let current flow from a 24v power supply and light up 6 banks of white LEDs. This entire setup was working great on an esp32wroom I bought from our school's shop - like I said it is very simple - but after ordering more esp32's online, I was greeted with slightly different looking ones that don't behave the same even when running the exact same code. Yes, I have verified that the pinout is the same on these two boards, although the footprint of the online boards (best datasheet I could find linked above) is one breadboard slot thinner.
Expected behavior:
I power it on, and nothing should happen until I connect pin 14 to ground, then the lights should turn on for a tenth of a second, then back off.
Actual Behavior:
I power it on, 3 banks of lights turn on rather dimmly. The other three stay off. When I connect pin 14 to ground, the three that were off turn on for a tenth of a second, then back off. While they are on, a blue light on the nodemcu-32s dev board turns on as well...
I did some digging:
On this random nerd tutorials website I found code that identifies which pins are your board's default SPI pins and when I ran it, I found that 3 of the 6 pins I was currently using (pins 23, 19, and 5) are SPI-related ones. These were in fact the pins that behaved correctly (they were off until 14 was pulled low.)
I am not sure if this is related to the root cause of my issue or not, but it seems suspicious. Any tips from you wise arduino wizards would be appreciated - this was supposed to be simple!
Code:
Below is the code I am using. You can ignore the rgb LED stuff (LED_PIN, NUM_LEDS, BRIGHTNESS, etc.) All that matters for what I am trying to get working here are the led banks connected to pins 23, 21, 19, 5, 16, and 2. I intentionally avoided pins 6-11 because many sites were saying to avoid them.
#include <Adafruit_NeoPixel.h>

#define LED_PIN 15      // Pin connected to the Data Input of WS2812B
#define NUM_LEDS 24     // Number of WS2812B LEDs in the strip
#define BRIGHTNESS 200  // Set the brightness (0-255)

#define SHUTTER_PIN 14  //Pin connected to the shutter signal of the cameras via 3.5mm jack
Adafruit_NeoPixel strip;

void setup() {
  // setup code here, to run once:
  pinMode(23, OUTPUT); // set each bank of 6 White Leds as outputs
  pinMode(21, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(2, OUTPUT);

  // set the shutterPin as a normally-high input
  pinMode(SHUTTER_PIN, INPUT_PULLUP);

  // To control rgb leds
  strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
  strip.begin();
  strip.setBrightness(BRIGHTNESS);
  strip.show();

 // Initialize all pixels to off
  digitalWrite(23, LOW);
  digitalWrite(21, LOW);
  digitalWrite(19, LOW);
  digitalWrite(5, LOW);
  digitalWrite(16, LOW);
  digitalWrite(2, LOW);
}

void loop() {
  //main code here, to run repeatedly:
  // if the shutter signal drops, flash on and off
  if (digitalRead(SHUTTER_PIN) == 0) {
    digitalWrite(23, HIGH);
    digitalWrite(21, HIGH);
    digitalWrite(19, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(16, HIGH);
    digitalWrite(2, HIGH);
    delay(500);
    digitalWrite(23, LOW);
    digitalWrite(21, LOW);
    digitalWrite(19, LOW);
    digitalWrite(5, LOW);
    digitalWrite(16, LOW);
    digitalWrite(2, LOW);
    delay(500);
  }
}

Could you provide the code you are using and all of the pin numbers, not just the three that work? From a quick look-up, it doesn't seem like you could actually use IO14 as GPIO14 on ESP32S and you shouldn't use any GPIOs from 6 to 11, unless you really know what you are doing, as those are connected to the internal SPI flash on the chip.

I just added the code that it's running, thanks for your time! Yes, I avoided pins 6-11. Also, why wouldn't I be able to use pin 14 as an input?

I was wrong, you are able to use the pin 14 as a GPIO, reading thru this manual a bit more thoroughly.

From the schematics, I can see that IO2 is for the board's blue LED. So that's probably your first problem... From this PDF, I see that IO21 is VSPIHD, Hold for Flash chips. No good. IO16 is HS1_DATA4, also used for the Flash chip. Also no good. You'll have to pick other pins.

The other issue is SIX pins supposed to deliver 3.3 volts at the same time. On a small ESP board. Not sure that's gonna happen...

Thanks for your response dda!

Why would a pin be labeled as a GPIO if in can't be properly used as a general purpose input or output? As in, shouldn't they just be labeled as just VSPI_HD etc instead to avoid confusion?

@Zach I don't think that's an issue, most of the pins on modern MCUs have multiple functions--you decide which ones to utilize. Checking the schematics, I don't see any external quad-SPI peripherals (as dda indicates, most commonly used for flash chips). Another indicator is that it's probably not the pins (aside from GPIO2, we've conclusively established that it's linked to a blue LED...but why is the LED bank dimly lightning up during initialization?) it worked with other ESP32-Wroom modules, which are also the modules used on the NodeMCU-32S board(s).

@Zach okay, I checked on the Espressif docs and yes, pin 16 is indeed not recommended to be used as a GPIO pin (it still can be, of course, but it could lead to unknown behavior as you've experienced)--nothing about pin 21 though.

@Zach it is possible to have different functionalities on the same pin - just don't use them all at once. In the case of the VSPI pins, if there's no Flash chip, and the VSPI bus isn't inited (eg if the code checked whether there's a chip, and didn't deinit afterwards, oops), they can be used.

I'm still not quite sure what's going on, but to troubleshoot this I would do the following:

First of all, verify it's not a faulty board and try it with another one of the new ones that you've got. If that doesn't help, then do the following:

Move the digitalWrite-s up, above the NeoPixel initialization code. See if that helps with the start-up.
If that doesn't help, add pull-down resistors to the LED outputs (try 10kOhm).
The blue LED lights up because GPIO 2's output is connected to it, looking at the schematic on the website you've linked. You might want to switch this one to a different GPIO on the board you're using.
Check the transistor circuits for the LEDs that are not functioning correctly. You've not posted anything related to it, so I can't help you much there, but if you do link it we might be able to use that info.

Will do, thanks

@Zach do you have an oscilloscope on hand? At least a multi-meter? If you run the main as an empty function, do the 3 LED banks still light up, even though dimly? If you can, check the voltage from the pin to the ground. Take notes. Then, put the main loop back in and measure the voltage on the pins with LED banks that aren't lightning up. What do you see? Of course, you could try just try other pins and if they work alright, just make compilation defines for each board and that'll make it easier to recompile your program as needed.


text:
RFM9x LoRa Radio code will compile with Uno but not Nano Every
I have code involving the use of an Adafruit Ultimate GPS Breakout v3 and an Adafruit RFM95W LoRa Radio that will compile with an Uno Rev3 but not with a Nano Every. The code I'm using comes almost directly from the examples provided by Arduino. I tried just the GPS code using the GPS_SoftwareSerial_Parsing test from Arduino and that worked, but I when I try using the Feather9x_TX code from Arduino it does not and I am not sure why. I am new to using Arduinos and have little experience with coding. I have attempted to search my error messages but have not been able to really find any answers so any help would be useful.
Here's the code
#include <SPI.h>
#include <RH_RF95.h>

#define RFM95_CS 9
#define RFM95_RST 8
#define RFM95_INT 2

// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup()
{
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

  Serial.begin(115200);
  while (!Serial) {
    delay(1);
  }

  delay(100);

  Serial.println("Feather LoRa TX Test!");

  // manual reset
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  while (!rf95.init()) {
    Serial.println("LoRa radio init failed");
    Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
    while (1);
  }
  Serial.println("LoRa radio init OK!");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
  // you can set transmitter powers from 5 to 23 dBm:
  rf95.setTxPower(23, false);
}

int16_t packetnum = 0;  // packet counter, we increment per xmission

void loop()
{
  delay(1000); // Wait 1 second between transmits, could also 'sleep' here!
  Serial.println("Transmitting..."); // Send a message to rf95_server

  char radiopacket[20] = "Hello World #      ";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);
  radiopacket[19] = 0;

  Serial.println("Sending...");
  delay(10);
  rf95.send((uint8_t *)radiopacket, 20);

  Serial.println("Waiting for packet to complete...");
  delay(10);
  rf95.waitPacketSent();
  // Now wait for a reply
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  Serial.println("Waiting for reply...");
  if (rf95.waitAvailableTimeout(1000))
  {
    // Should be a reply message for us now
    if (rf95.recv(buf, &len))
   {
      Serial.print("Got reply: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
    }
    else
    {
      Serial.println("Receive failed");
    }
  }
  else
  {
    Serial.println("No reply, is there a listener around?");
  }

}

And here are the errors
Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano Every, None (ATMEGA4809)"

C:\Users\jfeze\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp: In member function 'virtual void RHHardwareSPI::attachInterrupt()':
C:\Users\jfeze\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp:49:25: error: 'virtual void SPIClassMegaAVR::attachInterrupt()' is private within this context

     SPI.attachInterrupt();
                         ^

In file included from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead/RadioHead.h:731:0,
                 from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead/RHGenericSPI.h:10,
                 from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead/RHHardwareSPI.h:10,
                 from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp:7:

C:\Users\jfeze\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\libraries\SPI\src/SPI.h:186:15: note: declared private here

   inline void attachInterrupt() { SPI0.INTCTRL |= (SPI_IE_bm); }
               ^~~~~~~~~~~~~~~

C:\Users\jfeze\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp: In member function 'virtual void RHHardwareSPI::detachInterrupt()':
C:\Users\jfeze\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp:56:25: error: 'virtual void SPIClassMegaAVR::detachInterrupt()' is private within this context

     SPI.detachInterrupt();
                         ^

In file included from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead/RadioHead.h:731:0,
                 from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead/RHGenericSPI.h:10,
                 from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead/RHHardwareSPI.h:10,
                 from C:\Users\jfeze\Documents\Arduino\libraries\RadioHead\RHHardwareSPI.cpp:7:

C:\Users\jfeze\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\libraries\SPI\src/SPI.h:187:15: note: declared private here

   inline void detachInterrupt() { SPI0.INTCTRL &= ~(SPI_IE_bm); }
               ^~~~~~~~~~~~~~~

Multiple libraries were found for "RH_RF95.h"
 Used: C:\Users\jfeze\Documents\Arduino\libraries\RadioHead
 Not used: C:\Users\jfeze\Documents\Arduino\libraries\RadioHead-master
exit status 1

Error compiling for board Arduino Nano Every.

what is your specific question?

So far as I can tell, the library simply incompatible with your board. The functions they're trying to use are essentially commented as "don't use these" in the core(s). In the megaavr core that the Nano Every uses they were made private:.  For what it's worth, the functions they're used from appear to be in turn used nowhere in the project. So, I commented out the calls. However the library fails to compile owing to other differences in architecture. Basically you need a port for the megaavr core. I do not have a suggestion one for. You may not actually need RadioHead at all though.


text:
Need Digistump library for QWERTY keyboard and Fixes for my issues!
Hello there I am trying to install Digistump library to support ATTiny85 by digispark. But I am encountering a problem when trying to install Digistump AVR boards after adding an additional board URL preference as the library doesn't shows up after searching.I dont know what's the problem even after I tried from the fixes from other solutions across the web.

So, I made an alternative method to work the board by installing ATTinyCore library. But it doesn't support DIGIKEYBOARD actions. So when I try to download from library manager there is only packages for AZERTY & Belgian AZERTY layout.

So for me I need a package that support QWERTY layout. How to install the library.?

The description of DigiKeyboardFr says it is “based on
DigisparkKeyboard library”, and gives the link to that library.
DigisparkKeyboard doesn't seem to be available from the Arduino library
manager: you will most likely have to install it manually. Manual
installation of Arduino libraries is widely documented.

May I know how to install it manually?? for the specified keyboard layout..


text:
Arduino bluefruit nrf52 - check if softdevice is "busy"
I'm using a Bluefruit nRF52 with Arduino framework, and using Bluefruit library. It's connected to the Bluefruit connect app, but also acting as an SPI slave for another device (an stm32).
I'm having to bit-bang the SPI as the Arduino SPI library won't work as a slave (for nordic nrf52 devices), and using a GPIO from the nRF52 to tell the stm32 I'm ready to receive SPI (normally 5 to 10 bytes), after it detects SPI nCS assertion. To bitbang the SPI data, I'm then waiting on an interrupt on rising edge SPI CLK, at which point clock in the MOSI data.
It's mostly working except the odd message (1 in 5ish full transfers) gets missed. I've traced this to one SPI clk interrupt being missed during the transfer. (each transfer is 10 bytes).
As the nrf52 softdevice has higher priority than any user code, including interrupt handlers - I'm wondering if the irq is being missed because it happens during a period where the softdevice is in control. which is asynchronous.
So I'm wondering if I wait until soft device takes control, then wait till its done, then I signal that I'm ready to receive over SPI, that will give me the best chance to receive a full message.
Is there a way that I can poll some flag / variable / register to know that the softdevice has just been busy?

It has SPI Slave (SPIS) with EasyDMA so you could just use that instead. But I suppose you are afraid of events and tasks and that semaphore

Hi KIIV thanks for the reply.  i can see the SPIS in the nordic low level files but its not implemented in the arduino SPI library.  i tried to make my own version (SPI.h and SPI_nrf52832.cpp) to handle SPIS but couldnt get it to work.


text:
What is the relationship between the gain on the receiver and the delay time
I was conducting some research on wireless communication between a simple transmitter and receiver module using an Arduino. Now, I tested the channel accuracy and i received 14% error for a delay of one micro second. For a delay of 2 microseconds, my error was 0%, and for three microseconds, my error rate was 30%. I am not quite sure why the data would result in this. I think it possibly has something to do with the gain on the receiver and the delay time. Some sweet spot perhaps? Can anyone offer me some ideas/explanations? Also, sorry for any confusion in this question. I am happy to clarify.
Part 2:
Hey Everyone,
I also had a question regarding what purpose each of the following delay serves in wireless communication.
// Write each of the 8 bits
for (uint8_t i = 8; i > 0; --i)
{
  if (b & 1) // choose bit
    *reg |= reg_mask; // send 1
  else
    *reg &= inv_mask; // send 0

  tunedDelay(delay);// line in question ---------------------
  b >>= 1;
}

and the delay used in the regular blink program.
The regular delay used in the blink programs was what set the 2 microsecond delays.
Lastly, I am looking at the read and recv methods in the software serial library and i don't see any checks for start bits, so what's the point of writing one in the write method?

Related to Basic Serial Transmission Protocol and How to find the deferenced value of a transmit Port Register?. The bit of code you are quoting is from SoftwareSerial, and the delay is what makes the bits come out at the intended baud rate. The regular delay used in the blink programs was what set the 2 microsecond delays. - what do you mean by that?

So, you can open up the Arduino IDE, and type in delay(x) without have to physically import any new libraries other than the ones automatically inherited. That delay is what i am referring to.

How do I link other posts? Is it something I have to do elsewhere? Or do i just link them on the post and they will automatically show up as linked posts?

"Lastly, I am looking at the read and recv methods in the software serial library and i don't see any checks for start bits, so what's the point of writing one in the write method?" ... So that you can communicate with hardware UARTs, which do require a start bit...

How do I link other posts? - if you mention another StackExchange post it is automatically added to the linked posts.

Now, I tested the channel accuracy and i received 14% error for a delay of one micro second. For a delay of 2 microseconds, my error was 0%, and for three microseconds, my error rate was 30%.

Microsecond resolution delays on an Arduino are tenuous at best.  They aren't that accurate.  Simply because you're hitting the limit of the speed of the CPU.
At 16MHz you have a clock period of 1/16000000 seconds.  That's 63ns.  That's the granularity of the delays you can achieve - and that can only be achieved by inserting a precise number of NOP assembly instructions.
So for the best 1µs delay possible you would need (0.000001 / 0.000000063) 15.87 NOP instructions.  Of course, you can't have that many, so you have to round it either up or down.  Normal integer truncation would result in 15.  So that would actually be a delay of 945ns, which is an error of 5.5%.
2µs would be (0.000002 / 0.000000063) 31.74 NOP instructions, which would round to 31, so 1.953µs, or an error of 2.35%.  As you can see increasing the length generally reduces the error.
HOWEVER
The delay function on the Arduino for microsecond accuracy (delayMicroseconds()) is maybe not as accurate as it could be.  Simply because it's impossible to just have an exact number of NOP instructions for a delay since you can't know how long the delay should be until the function is called with a parameter detailing how long the delay should be.  So it has to perform a number of calculations and make a number of assumptions.  It tries to come close, but it was written for one specific version of the compiler and compilers change. Things may have been changed in how the function gets called, and how long parts of it take (what registers are pushed and popped may change with different compiler versions, for instance).  So it's not a perfectly reliable delay.
For more detail you can look at the source code of it (it's in wiring.c) and you can see how for small delays it's very hard to get it right. For instance, this couple of lines highlights the problem nicely:
    // for a one-microsecond delay, simply return.  the overhead
    // of the function call yields a delay of approximately 1 1/8 us.
    if (--us == 0)
        return;

Note the use of the word approximately there...
Also you need to note that the delay functions are just that - a delay at that specific moment in time from the start of the call to its finish.  It doesn't take into account anything else that's going on in your code, so a delay of 1µs in a loop of code that does other things will end up in a loop that takes X + 1µs where X is the amount of time that the rest of the code takes to execute.
And that's where the tunedDelay() function comes in.  It has been specially written to be used in that specific circumstance to provide a delay that takes into account the time the rest of the loop takes to run.  That is, the loop's time plus the tunedDelay time equate to the final period you want for the whole loop.  For asynchronous serial communications the timing accuracy is important.  Since there is no separate (or even embedded) clock to get the timing from both ends have to agree what speed the communication happens at (the baud rate), and any deviation from that can cause communication errors.  So the timing has to be as close as possible. A normal delayMicroseconds() function call just wouldn't cut the mustard - they needed it more precise than that.  Manually tuned to have specific delay values that are as precise as possible, and that was done for specific baud rates on specific speed chips.  Each supported frequency has a table such as this:
static const DELAY_TABLE PROGMEM table[] =
{
  //  baud    rxcenter   rxintra    rxstop    tx
  { 115200,   1,         17,        17,       12,    },
  { 57600,    10,        37,        37,       33,    },
  { 38400,    25,        57,        57,       54,    },
  { 31250,    31,        70,        70,       68,    },
  { 28800,    34,        77,        77,       74,    },
  { 19200,    54,        117,       117,      114,   },
  { 14400,    74,        156,       156,      153,   },
  { 9600,     114,       236,       236,      233,   },
  { 4800,     233,       474,       474,      471,   },
  { 2400,     471,       950,       950,      947,   },
  { 1200,     947,       1902,      1902,     1899,  },
  { 600,      1902,      3804,      3804,     3800,  },
  { 300,      3804,      7617,      7617,     7614,  },
};

That's the value to send to the tunedDelay() function in the four different situations where its used for each of the baud rates at that specific clock frequency (16MHz in that example).
tunedDelay() itself is written in assembly code and is a very tight loop for the number of iterations specified in the parameter.  The shortest possible piece of code with the minimum of overhead to get the maximum accuracy and finest granularity (least number of clock cycles for one iteration) out of it.

Thank you so much sir. That was an amazing answer. Thank you so much!

Can you please explain what are the purposes of rxcenter, rxintra, rxstop, and tx?

They are how long to wait before looking at the state of the line for a specific bit (rx...) or how long to wait between sending each bit (tx)

So does rxcenter wait that many nanoseconds after receiving the startbit, the rxintra waits that many ns between each subsequent payload bit, and the rxstop waiting that long for the stop bit(even though there is no stop bit)? Am I understanding that right? ^^

It's not nanoseconds - its loop counts, but that is pretty irrelevant, it's just a period of time.  rxcenter starts the reading at the center of a bit - give it time to arrive, but not too long - just the first bit after the leading edge of the start bit.  rxintra is how long to wait between each successive bit, and rxstop is how long to wait to sample the stop bit.  tx is like rxintra but for transmitting.

yes, so that "how long to wait" part is in nanoseconds i presume?

I said no, it is not nanoseconds, it is loop counts. You could calculate how long it is by counting the instructions in the loop and working out how many clock cycles in total the loop takes, multiplying it by that number.

I am looking at the read and recv methods in the software serial library and I don't see any checks for start bits, so what's the point of writing one in the write method?

The start bit is absolutely essential in serial comms. In the graphic below, the start bit is marked "B" - which distinguishes it from "idle" data which is "A". Once received, the receiver then waits 1.5 bit times and starts clocking in the remaining bits. (Starting at "C" in the diagram, and then moving on for a total of 8 bits).

Without a start bit, how would the receiver know when the byte started? Imagine you wanted to send 0xFF (all 1 bits). Without a start bit that would be indistinguishable from the idle state.
In the graphic, "D" is the stop bit. Why have a stop bit? We need one (which is a "1" bit), so that we can detect the transition from the stop bit in the previous byte (a "1") and the start bit in the next byte (a "0").
In the graphic, "E" is the start bit for the next byte.

I don't see any checks for start bits ...

SoftwareSerial has a pin-change interrupt set up to detect that the receiving pin has changed state (to a zero usually). That is your start bit. You don't see it in the loop, because it has already arrived, otherwise you wouldn't be in the receive loop in the first place.

Hey @NickGammon, i have a question. So let's say the receiver is high, and it reads a 0 not because of the write function but because of interference/noise, and so it says, ok time to read 1 byte. How come it doesn't take the next 8 bits, and covert it into a integer? However, when the write sends a 0, it quickly converts the next 8 bits into a integer. How does this get resolved? Or am I completely missing the ball park here?

Also, i believe this is the line you're referring to regarding reading the start bit: if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) and uint8_t SoftwareSerial::rx_pin_read() {   return *_receivePortRegister & _receiveBitMask; } So because the pin is on high, rx_pin_read will always return 1 in that register right? In which case, !rx_pin_read will evaluate to false won't it? never going into that if statement. Or am I totally off?

That is because it is a pin-change interrupt, which responds to a change in state. That line tests whether we are changing to the right state (normally from 1 to 0). The reason we are there in the first place is because of the interrupt.


text:
How to find the deferenced value of a transmit Port Register?
So I am working with the SoftwareSerial library. I'm looking at the write function and I see a *reg value being manipulate. I want to find the value of *reg so I traced the value by stepping into each function call.so here we go.
*reg = _transmitPortRegister
_transmitPortRegister = portOutputRegister(port) //I'm working with pin 1 in register D

Continuing...
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )

const uint16_t PROGMEM port_to_output_PGM[] = {
    NOT_A_PORT,
    NOT_A_PORT,
    (uint16_t) &PORTB,
    (uint16_t) &PORTC,
    (uint16_t) &PORTD,
};

My first question is what is the point of (uint16_t) &PORTD? I am assuming that's just the value of PORTD's register because it is being anded with an empty 16 bit int.
Continuing on,
#define PORTB _SFR_IO8(0x05)
#define PORTC _SFR_IO8(0x08)
#define PORTD _SFR_IO8(0x0B)

#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#define __SFR_OFFSET 0x20

#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

Now, I followed it all the way here. But how do I find out what actually is the deferenced value? Since this is all IDE, i'm not sure how to GDB this either.
LASTLY, the write function takes in a parameter b, which is a byte. Now in the write function, this is the code to write.
// Write each of the 8 bits
for (uint8_t i = 8; i > 0; --i)
{
  if (b & 1) // choose bit
    *reg |= reg_mask; // send 1
  else
    *reg &= inv_mask; // send 0

  tunedDelay(delay);
  b >>= 1;
}

In that block of code, I am not quite sure why they are doing b & 1. Are they just anding the whole byte with 1? If so, then why comment it as "choose byte"
and inside the if-else blocks, they're just oring *reg with reg_mask. How does that translate to sending a one?
Sorry for any confusion, i am glad to clarify any confusing parts of this question. Please let me know.

My first question is what is the point of (uint16_t) &PORTD? I am assuming that's just the value of PORTD's register because it is being anded with an empty 16 bit int.

No.  You're mistaking the operator.  In this context & means the address of, so it is getting the address of the variable called PORTD and casting it to an unsigned 16-bit integer, which it's then storing in the array.

Now, I followed it all the way here. But how do I find out what actually is the deferenced value? Since this is all IDE, i'm not sure how to GDB this either.

Again, we're talking addresses.  The port register number is (for port D) 0x0B.  Add that to 0x20 and you get 0x2B which is the address of the register in memory.  Then comes the tricky bit:
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

Expand that out with 0x2B and you get:
(*(volatile uint8_t *)(0x2B))

Now, working from the inside out we have:
(volatile uint8_t *)(0x2B)

That says this is a pointer to address 0x2B.
Then that is de-referenced to get the value from that pointer with a * operator:
*(volatile uint8_t *)(0x2B)

So you end up with "The value that is in the address 0x2B"
If we then feed that back into the first part of your question, so:
PORTD = (*(volatile uint8_t *)(0x2B))

then &PORTD would be:
&(*(volatile uint8_t *)(0x2B))

The initial & and * cancel each other out (you can think of them as opposites - one is get the address from a value, the other get a value from an address), so you effectively end up with:
(volatile uint8_t *)0x2B

Oh my, i feel so amateurish. I am so sorry. I can't believe I completely neglected the fact that the & is adress of in this case. Ok, thank you so much! So I know up the value in 0x2B is being deferenced. But are you saying 0x2B is the value that is being returned? or is it something else still?

0x2B is the value that is being returned when & is used, since that is the address that the value is stored at.  Don't sweat it, it took me years to get my head around pointers.

OOO! the value at 0x2b is being deferenced, and we're trying to find out the address of that value. which IS 0x2b. Thank you so much. Also, why would or *reg |= reg_mask send a one? If i'm using pin 1, then reg_mask equals 0b00000010. so 0b00101011 | 0b00000010 is what is being calculated. but how does that translate to a one being sent? there isn't even a digitalWrite in that block of code.

That would OR the contents of reg_mask with the contents of the address pointed to by reg.  It basically sets one bit in the register. &= inv_mask clears the same bit.

sorry, I'm not quite understanding how it sets one bit in the register because that OR statement evaluates to 0b00101011.

Also, just be setting it in the register, how does it actually transmit it? In other words, when does it actually power the pin HIGH and LOW?

It expands to *reg = *reg | reg_mask.  If *reg contains, say 0b00101001 and reg_mask contains 0b00000010 then *reg ends up as 0b00101011 and the pin goes high.  That register is more than just memory - it is actually the physical hardware of the IO pin. You're not just setting values, you're directly affecting real hardware. By setting a bit in the PORT register you are physically changing the voltage level on the pin from 0V to 5V.

Hey, O i see what you're saying. Ok, i just read up on what each register does in arduino. But here's the iffy part. *reg is 0x2b. That evaluates to 0b00101011. So ORing that with 0b00000010 just gives me back 0b00101011.

No, reg is 0x2b, *reg is whatever is at 0x2b.

Hmm, so how do I figure out what is at value 0x2b?

By looking at *reg or PORTD. Why do you need to "figure out" what is at that address anyway? You are just setting or clearing one bit in it. The rest shouldn't concern you

well i was told to figure out what exactly is the startbit. So all of this is just to figure out what startbit is being sent. So am i understanding this properly? the value 0x2b is being transmitted as the startbit?

Nonono!  There is NO VALUE 0x2B.  That is an ADDRESS in memory.  The value that is being sent is ONE of the bits within the CONTENTS of that address.  You don't need to know what the contents are, since you are only ever manipulating ONE bit within it, and you never care what it was, only what you set it to.  Forget that whole register and look at the rest of the program to determine what the bit is being set to and when. Forget the mechanics of how the bit is being set.

Oh I completely understand! ok ok. That makes more sense. Hence this piece of code in the library. And if i just had an arduino uno, the inv would read false, since most arduinos don't use inverse logic. So basically, my start bit is 0, since i'm anding it with inv_mask.
// Write the start bit
if (inv)
*reg |= reg_mask;
else
*reg &= inv_mask;
Thank you so much for your help.

// Write each of the 8 bits
for (uint8_t i = 8; i > 0; --i)
{
  if (b & 1) // choose bit
    *reg |= reg_mask; // send 1
  else
    *reg &= inv_mask; // send 0

  tunedDelay(delay);
  b >>= 1;
}

In that block of code, I am not quite sure why they are doing b & 1. Are they just anding the whole byte with 1? If so, then why comment it as "choose byte" and inside the if-else blocks,

The comment is: choose bit
First, variable b is the byte that is being set. Now, since async serial sends the least-significant bit first, at the start of the loop of 8 iterations, it takes the low-order bit to see if it is set or not:
  if (b & 1) // choose bit

If set, it sets the output port to HIGH (by ORing in the appropriate mask to the appropriate register), otherwise it sets the port to LOW (by ANDing in the appropriate inverted mask to the appropriate register). The inverted mask would be set to every bit but one.
Now look at this:
  b >>= 1;

That shifts the bits right one, throwing away the low-order bit. Now what was previously the second lowest-order bit is now the low-order bit. Then the loop repeats. Now the next bit is sent. And so on for 8 bits.
Imagine we were sending 0x39 (0b00111001). For the 8 iterations of the loop we would see:
00111001  --> 1 sent, then "b" shifted right one
00011100  --> 0 sent, then "b" shifted right one
00001110  --> 0 sent, then "b" shifted right one
00000111  --> 1 sent, then "b" shifted right one
00000011  --> 1 sent, then "b" shifted right one
00000001  --> 1 sent, then "b" shifted right one
00000000  --> 0 sent, then "b" shifted right one
00000000  --> 0 sent, then "b" shifted right one

You can see that the right-most bit is sent (the low-order bit) and then b is shifted right (introducing zeroes at the left), until all 8 bits are sent.


text:
How does the speed work in VirtualWire Library
I'm analyzing the VirtualWire library and in it, the send messages are being sent with digitalWrite in the "send" method. However, there is a setup speed function. I'm reading that function and I see a lot of prescalers and TCCR variables. However, I'm not quite sure what these things do. Because, if it uses digitalWrite anyway to send the bits, then really is no intrabit delay, etc. Can someone please clarify this?
Sorry if question is convoluted. Happy to do any clarification. Thank you for all guidance!
EDIT: Also, how do I transmit a block of message. Something greater than a byte? I'm trying to calculate BLER of messages and software serial only transmits 1 byte at a time. While virtualWire uses low-level error detection (and i want to avoid the use of any error detection/correction).

@NickGammon any thoughts on this? Main question is actually the edit.

I think that is used for receiving. By setting the speed, it knows how often it needs to read the input pin. It does this using timer interrupts, so it will run "in the background" without interfering with the main (loop) code.
The TCCR stuff is the set the interval for the timer interrupt.

So, as far as the bit transmission is considered, it only uses digitalWrite to send it right? As opposed to how SoftwareSerial directly accesses the registers.

Also, I only see digitalWrite being called once. and not in a loop. Am i reading the code wrong? How is it being able to transmit so many bytes? Sorry if I''m completely overlooking things.

Sorry, on a second look at your post, i am slightly confused. So does that mean delays ARE or AREN'T being used during transmission? Some clarification here please? thank you!

Yes, it only uses digitalWrite (not the fastest, but very portable). Looking at the code a bit better, it seems their are using the timer interrupt to both send data, as well as receive (though not at the same time). I didn't say anything about the TX side in my question. But seeing that they also use the timer for TX, their won't need any delays. So sending data is done "in the background" as well. Just like hardware serial.


text:
AccelStepper Library: How do I go to a position without decelerating?
When I make the motor move at a certain distance with setMaxSpeed(), setAcceleration(), and moveTo(), it always accelerates and decelerates. Is there a way to disable the deceleration?

Acceleration and deceleration causes less mechanical stress. Why don't you want that?

Because I am trying to make it move in accordance to a set of acceleration data from an earthquake, and it seems weird that per value of acceleration (and distance from double integration), it accelerates and decelerates (and if the differences are too low, the motor can easily be heard vibrating)

AccelStepper, as hinted by the name, uses acceleration always. By setting the acceleration high, you reduce the amount of time spent accelerating to the set speed.
setAcceleration() sets the rate in steps per second per second. If your MaxSpeed is 200 steps per second, then setting the acceleration to 200*10 means all acceleration is over in 1/10 second. You can go higher, etc.


text:
How to make a stepper motor move at sinusoidal acceleration?
I am new to arduino but I know basic concepts. How do I make the motor move at sinusoidal acceleration? I used the accelstepper library and it seems that at the end of each loop of distance with acceleration, the motor abruptly stops and begins accelerating again. Is there any way to stop this abrupt pause?

wow, you're doing this code line by line from answers here

Similar questions: https://forum.arduino.cc/index.php?topic=557838.0 and https://forum.arduino.cc/index.php?topic=365301.0  Symplaz, is this for school? Please show us your sketch.