1

I wrote the following code that outputs a packet data structure bit by bit.

I do this using two for loops. These two for loops should always terminate, but the presence of analogWrite() makes them not terminate.

More concretely:

#define PACKET_SIZE 2
#define NUM_BITS 8

#define LOGICAL_LOW 127
#define LOGICAL_HIGH 255
#define LOGICAL_NULL 0

#define DATA_OUT_PIN 13
#define DATA_IN_PIN 3

#define DELAY 200

struct packet {
  byte content[PACKET_SIZE];
  byte checksum;
};
void testFun(struct packet *p) {
  for (int i = 0; i < PACKET_SIZE; i++) {
    byte m = 1;
    for (int j = 0; j < NUM_BITS; j++) {
      Serial.println(i);
      if ((p->content[i] & m) == m) {
        analogWrite(DATA_OUT_PIN, LOGICAL_HIGH);
      }
      else {
        analogWrite(DATA_OUT_PIN, LOGICAL_LOW);
      }
      m <<= 1;
    }
    Serial.println(i);
  }
  Serial.println("Other loop");
  for (int i = 0; i < NUM_BITS; i++) {
    byte m = 1;
    if ((p->checksum & m) == m) {
      analogWrite(DATA_OUT_PIN, LOGICAL_HIGH);
    }
    else {
      analogWrite(DATA_OUT_PIN, LOGICAL_LOW);
    }
    Serial.println(i);
  }
  analogWrite(DATA_OUT_PIN, LOGICAL_NULL);
}
void setup() {
  Serial.begin(115200);
  pinMode(DATA_OUT_PIN, OUTPUT);
  pinMode(DATA_IN_PIN, INPUT);

  struct packet p;
  p.content[0] = 127;
  p.content[1] = 98;

  delay(3000);
  testFun(&p);

}

loops forever but this one doesn't:

#define PACKET_SIZE 2
#define NUM_BITS 8

#define LOGICAL_LOW 127
#define LOGICAL_HIGH 255
#define LOGICAL_NULL 0

#define DATA_OUT_PIN 13
#define DATA_IN_PIN 3

#define DELAY 200

struct packet {
  byte content[PACKET_SIZE];
  byte checksum;
};
void testFun(struct packet *p) {
  for (int i = 0; i < PACKET_SIZE; i++) {
    byte m = 1;
    for (int j = 0; j < NUM_BITS; j++) {
      Serial.println(i);
      if ((p->content[i] & m) == m) {
        analogWrite(DATA_OUT_PIN, LOGICAL_HIGH);
      }
      else {
        analogWrite(DATA_OUT_PIN, LOGICAL_LOW);
      }
      m <<= 1;
    }
    Serial.println(i);
  }
  Serial.println("Other loop");
  for (int i = 0; i < NUM_BITS; i++) {
    byte m = 1;
    if ((p->checksum & m) == m) {
      analogWrite(DATA_OUT_PIN, LOGICAL_HIGH);
    }
    else {
      //analogWrite(DATA_OUT_PIN, LOGICAL_LOW);
    }
    Serial.println(i);
  }
  analogWrite(DATA_OUT_PIN, LOGICAL_NULL);
}
void setup() {
  Serial.begin(115200);
  pinMode(DATA_OUT_PIN, OUTPUT);
  pinMode(DATA_IN_PIN, INPUT);

  struct packet p;
  p.content[0] = 127;
  p.content[1] = 98;

  delay(3000);
  testFun(&p);

}

the difference between these two being a single commented line in testFun

My entire sketch is as follows:

#define PACKET_SIZE 2
#define NUM_BITS 8

#define LOGICAL_LOW 127
#define LOGICAL_HIGH 255
#define LOGICAL_NULL 0

#define DATA_OUT_PIN 13
#define DATA_IN_PIN 3

#define DELAY 200

struct packet {
  byte content[PACKET_SIZE];
  byte checksum;
};
void testFun(struct packet *p) {
  for (int i = 0; i < PACKET_SIZE; i++) {
    byte m = 1;
    for (int j = 0; j < NUM_BITS; j++) {
      Serial.println(i);
      if ((p->content[i] & m) == m) {
        analogWrite(DATA_OUT_PIN, LOGICAL_HIGH);
      }
      else {
        analogWrite(DATA_OUT_PIN, LOGICAL_LOW);
      }
      m <<= 1;
    }
    Serial.println(i);
  }
  Serial.println("Other loop");
  for (int i = 0; i < NUM_BITS; i++) {
    byte m = 1;
    if ((p->checksum & m) == m) {
      analogWrite(DATA_OUT_PIN, LOGICAL_HIGH);
    }
    else {
      analogWrite(DATA_OUT_PIN, LOGICAL_LOW);
    }
    Serial.println(i);
  }
  analogWrite(DATA_OUT_PIN, LOGICAL_NULL);
}

void setup() {
  Serial.begin(115200);
  pinMode(DATA_OUT_PIN, OUTPUT);
  pinMode(DATA_IN_PIN, INPUT);

  struct packet p;
  p.content[0] = 127;
  p.content[1] = 98;

  delay(3000);
  testFun(&p);

}

void loop() {
  // put your main code here, to run repeatedly:

}

and its two outputs are 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 Other loop 0 1 2 3 4 5 6 7

and

0 0 0 ...

6
  • Please provide also a sample serial output, since this seems to be where you sense, that the loop goes on indefinitely. Is the loop() function empty? You didn't provide it. I don't see a obvious reason, why there should be an infinite loop, but I also don't see, why this should work. You don't wait for the signal to be outputted on the pin. You restart PWM so fast, that it cannot really do a cycle. You have to wait a bit, otherwise the code will be executed way too fast Commented Oct 7, 2019 at 6:48
  • The loop function is empty. The serial output for the first snippet is always 0 (implying i is never incremented) while that for the second loop is what you would expect and prints out “Other loop”. I tried adding a one second delay to prevent what you mentioned, and that didn’t work. Commented Oct 7, 2019 at 15:12
  • I loaded both codes (with an empty loop) on a Nano and they both worked identically. The behavior where one seemingly unrelated line completely changes the program is often due to undefined behavior at a completely separate point in the program. It can be really hard to find. Please post the complete program that will exhibit the problem. The error may be somewhere completely unrelated to this code. Commented Oct 8, 2019 at 1:24
  • Just added the entire sketch. Its pretty much identical to the first two snippets I gave. I also added the exact output I get on an Arduino Mega 2560 Commented Oct 8, 2019 at 3:23
  • 1
    What output did you actually expect?! The provided output is what I would expect from looking at your code... Commented Oct 8, 2019 at 16:07

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.