1
votes

I am writing a serial communication program between a mkr wifi 1010 and a mega in which the mkr sends either a H or L char to the mega, and the mega responds by reading the char and setting it's onboard LED to either high or low depending on the char. When I use delay(#) on the mkr the code works just fine and the mega's LED blinks on and off.

However when I create delay-less code the mega's led will not blink. It either stays low or stays high, most of the time stays low. I have checked the mkr code by reading the serial port and it indeed sends 72(H) and 76(L) alternately at the correct interval in both versions of the code.

Wiring diagram:

MKR          Mega
gnd    ->     gnd
tx     ->     rx
rx     ->     tx

I have level shifted the mega's tx pin down to 3.3v before the mkr's rx pin.

mkr delay code:

void setup()
{
  uint32_t baudRate = 9600;
  Serial1.begin(baudRate);
}

void loop()
{
  Serial1.print('H');
  delay(500);
  Serial1.print('L');
  delay(500);
}

mkr delay-less code:

unsigned long curT = 0;
unsigned long prevT = 0;
const int interval = 500;
int byteToSend = 'L';
void setup()
{
  uint32_t baudRate = 9600;
  Serial1.begin(baudRate);
}

void loop()
{
  curT = millis();
  
  if (curT - prevT > interval)
  {
    if (byteToSend == 'L')
    {
      byteToSend = 'H';
    }
    else
    {
      byteToSend = 'L';
    }
    
    Serial1.print(byteToSend);
    
    prevT = curT;
  }
}

mega code:

const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
}

void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0)
  {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'H')
    {
      digitalWrite(ledPin, HIGH);
    }
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'L')
    {
      digitalWrite(ledPin, LOW);
    }
  }
}

As far as I know these 2 different mkr programs do exactly the same thing and send serial data in the exact same way, it's just that one is blocking and one is non-blocking. Why is it that the delay-less code does not blink?

1
What do you mean by "doesn't work"? What happens? Is the light permanently on or off or blinking at the wrong speed?Mark Setchell
The light stays either on or off. Most of the time it stays off but every now and then it will stay on high, so maybe the first value is getting sent correctly but not after that first one.JGoss
You seem to be using an int (2 bytes) to send a byte. And to receive.Mark Setchell
That has solved it, thank you. Would you be able to elaborate on why that didn't work?JGoss
It means you send 2 bytes and compare them to the single character 'H' or 'L' so it is not going to work very often - only when the high byte happens to be zero and will get all out of sync - as you saw.Mark Setchell

1 Answers

1
votes

In the delay-less sender code:

int byteToSend

should be

char byteToSend

and in the receiver code:

int incomingByte

should be

char incomingByte

This fixes the issue.