Weird serial initialisation bug

so basically I've somehow solved the issue but I want to understand it a little more;
so I've got a nano every running a patch to send commands to neopixels leds from max/msp using the USB/serial.
When I open the patch without doing anything it doesn't work (and the RX seem to go on for a longer time that I send them).
If I send a DTR command it will reset the board and then it works.
I was desperate because it worked in the arduino IDE using the serial monitor and not in max. In fact it will work if I open my max patch; then open the arduino IDE with the serial monitor (the nano would then reset and then suddenly it would work in max).
Has somebody an idea why it would do that? for now I just activate the DTR on start inside max which will reset the nano but I don't see why I'd need this; is this just the reset that does the trick? If I disable the DTR (off) it doesn't reset and keeps working. I've never had this issue with standard nanos before

Welcome to the forum

What is a "max patch" ?

a max/msp patch. max/msp is a node-based programmation software

I am still none the wiser

Can you post a link to a page explaining what you are talking about ?

I must admit to be struggling with understanding this question as well. I did find this definition online:

Max objects communicate by sending each other messages through patch cords. These messages are sent at a specific moment, either in response to an action taken by the user (a mouse click, a MIDI note played, etc.) or because the event was scheduled to occur (by metro, delay, etc.).

Unfortunately it conveys very little to me. I also found this:

https://en.wikipedia.org/wiki/Max_(software)

From this i get a vague notion that a "patch" is somehow related to a MIDI event which might be programmed to send something to the serial port of the Nano. However, it is still some way off from being clear.

I think we need to understand:

  • what exactly is a MAX patch or "the patch" and how it relates to the Arduino
  • how the MIDI equipment is connected to the Nano - is there a MIDI breakout involved board for example?
  • see the code being run on the Nano

At this point it difficult to even speculate.

I don't think it matters much to understand exactly how max/msp works. It's a software you can do programmation with; that in this case sends data to the arduino through serial/usb. In this instance it has nothing to do with midi. It has a serial object and for the data to be correctly received I have to initialize the serial object with the DTR flag (I believe DTR is part of the serial protocol) which provokes a reset of the arduino and allows it to work. I don't know why.

here is the code on the nano:

#include <Adafruit_NeoPixel.h>

#define LED_PIN   6
#define LED_COUNT 8
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN);


//==========================setup()==========================================
void setup()
{
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
  Serial.begin(115200);               // 115200 is the default Arduino Bluetooth speed
  digitalWrite(13,HIGH);              ///startup blink
  delay(600);
  digitalWrite(13,LOW);
  strip.setPixelColor(0, 255, 0, 0);
  strip.show(); 
  delay(300);
  strip.setPixelColor(1, 0, 255, 0);
  strip.show(); 
  delay(300);
  strip.setPixelColor(2, 0, 0, 255);
  strip.show(); 
  delay(300);
  strip.clear();
  strip.show(); 
}
//===========================loop()============================================
void loop()
{ 
  
  while (Serial.available() > 0)
{ 
int cmd = Serial.parseInt();
int pixel = Serial.parseInt();
int R = Serial.parseInt(); 
int G = Serial.parseInt(); 
int B = Serial.parseInt(); 
  if (Serial.read() == '\n')
  {
  if (cmd == 0)
  {
  strip.setPixelColor(pixel,R,G,B);
  }
  if (cmd == 1)
  strip.clear();
  if (cmd == 2)
  strip.setBrightness(pixel);
  strip.show();
  }
  
}  
}

I've dabbled a little bit in MaxMsp; I've forgotten most of it. Just to show @UKHeliBob and @BitSeeker, I did dig this out from a backup

I think that this is called a patch and I think that the connecting lines are called patch cords.

There is a serial object at the bottom; the objects above control the serial port object. The serial object can be configured using serport and dtr above it.

If not mistaken, the @dtr refers to the dtr setting. I can't remember what the 1 was for; it might be that it actually reads @dtr 1.

When I open the patch from file, it opens the selected port. If I select and other port, it will close the existing port and open the new one applying the dtr setting.

I don't have a Nano Every so can't test. I do have a CH340 Nano, a FTDI SparkFun RedBoard (to simulate a real Nano) and an original Uno and Mega.

The following is observed behaviour

  1. With DTR enabled and selecting a port
    • All boards reset as expected when changing (and/or opening) the port.
    • No side effects on previously selected port or when closing the current port.
  2. With DTR disabled and selecting a port
    • The Uno and Mega do not reset when their port is selected/opened.
    • The Uno and Mega do not reset when their port is deselected/closed.
    • The CH340 Nano and FTDI RedBoard do reset when their port is selected/opened.
    • The CH340 Nano and FTDI RedBoard do reset when their port is deselected or closed.

I suspect that this is a driver kind-of-issue; I think that the Nano Every will behave the same as the Uno and Mega (and doesn't reset when DTR is disabled) but @grrrz might be able to confirm.

You are using a rather simplistic method of receiving the serial data, it would be very easy to get out of synchronization and have the various numeric fields get mixed up. Sending a DTR command may be causing the Nano Every to reset and properly synchronize the data being received.

This method works flawlessly and I've been using it on various projects without any issue. There's no way 'data could get mixed up'. I usually use standard nano boards so it's something to do with a bad initialization with the nano every specifically. A sketch should reset automatically once serial is called and here it doesn't work right until I call dtr.

Thank you for this thorough testing, I've changed the port back and forth (haven't tried closing it and opening it but that should be similar?), anyway doing this the arduino resets but still doesn't receive data correctly (it seems it receives for longer than I'm sending), only turning on dtr solves the issue (and reset). Turning it off does nothing. I've also done a similar patch with an old uno and had never had to do that either so it seems specific to the nano every. The arduino IDE serial monitor seems also to activate the right thing for it to work. If I have no further issue with this I'll call it a quirk of the every and move on.

When using the Nano classic, if an external device (even the Serial monitor) opens the Serial port the Nano resets and the sketch starts again.

I have no experience of the Nano Every, but I suspect that it is not reset when its Serial port is opened. This is not a bug. You have been depending on the way that a particular board works and have now switched to a different board that uses different hardware that implements the Serial interface differently

I have no experience of the Nano Every, but I suspect that it is not reset when its Serial port is opened. This is not a bug. You have been depending on the way that a particular board works and have now switched to a different board that uses different hardware that implements the Serial interface differently

Well that's not what happens; the board does reset each time my serial object is initialized (or closed; or opened again, and then it crashes); but the sketch still doesn't work as it's supposed to. It's only when DTR is on that it works. And I've been using nano; uno and mega boards for different projects with a very similar program to deal with serial (not neopixel though) and as far as reset is concerned they all behave like this (and as well I've been using boards with a raspberry and pure-data; a different program). Never had issue though.
So the fact it works is definitely related to this DTR feature not the reset; I suspect the serial monitor activates it somehow. It's either specific to the nano every or there's something specific with the nanopixel routine that causes this issue (it's the first time I'm trying neopixels). I also get an AVR error message when uploading at the beginning; and it feels like it's taking quite a long time to upload (but I suppose the neopixel library is quite big)

https://cycling74.com/forums/serial-obj-not-connecting-through-to-serial-com-port-to-accept-data-from-arduino#reply-630c5e4588afef3b5685f414
seems other people have a similar issue with max and a similar workaround

The DTR thing is quite normal for some Arduino boards. DTR is wired to reset (via a capacitor) so that when a connection is opened to the serial port, a reset is triggered which causes the bootloader to run. This checks whether an upload has been requested and either uploads the code or just proceeds to running the existing sketch. Its how the upload process is able to work on some boards. Of course, if the DTR signal is sent manually, it would have the same effect.

However, the DTR is just a means to reset the board which just happens to provides a convenient workaround. The question seems to be, why does the sketch not respond correctly when the serial port is kept open? Why is a reset necessary to be able to read the data correctly?

Do we know for sure that the line terminator is just '\n' and not '\r\n' (CRLF)? Because If the next character were not a '\n' and perhaps a '\r' instead, then the IF statement that follows would evaluate to false and everything within its scope would just not happen? The next time around the loop would also throw the first parseInt() command, because we still have a '\n' in the buffer.

Since the data is sent in a fixed format anyway, might it be simpler to just do a readline() after parsing the ints to clear to the end of the line, then go ahead and test for the value of cmd as at present before accepting the next batch of data? For example:

while (Serial.available() > 0)
{ 
  int cmd = Serial.parseInt();
  int pixel = Serial.parseInt();
  int R = Serial.parseInt();
  int G = Serial.parseInt();
  int B = Serial.parseInt();
  Serial.readline();   // Clear to the end of the current line
  if (cmd == 0)
    strip.setPixelColor(pixel,R,G,B);
  if (cmd == 1)
    strip.clear();
  if (cmd == 2)
    strip.setBrightness(pixel);
  strip.show();
  }
}

That way it doesn't matter whether the line is terminated with '\r\n' or just '\n'.

What throws me a bit is the last comment in the OP.:

Is this saying that you send just one DTR, the board resets and after that you don't need to send any further DTR and it keeps on working?

The only other thing that occurs to me is that the serial connection is getting dropped for some reason and needs a reset and a serial.begin to get it going again.

No time right now, but the answer likely lies in the schematics of these Arduinos - specifically look at how the DTR signal(it is a physical signal, not a protocol) connects, particularly to the reset of the micros. IIRC, which is questionable, in some the reset hits the actual micro, not just the USB interface device. There may lie the answer. Or not.

1 Like

Again, the board is actually reset when opening the serial object. It's not the issue. Somehow the serial initialization is not correct but it does reset, I can confirm this visually with my little startup animation. And I know for a fact I'm sendind the right line return (n) character because I convert my message to ascii (several numbers separated by spaces) and then add a 10 at the end which is the ascii line return code. I know exactly what I'm sending on this serial line and I know this method works fine as it has for the past ten years probably on similar projects I've made on a variety of boards, however not elegant people may find it. A reset occurs to init the serial connexion, that's how it has always worked. Other people using max say some boards need dtr enabled, that's what it is.

Fair enough, so if we are sire of the line ending being taken care of then we can rule that out. I don't have any further suggestion other than the serial connection getting dropped for some reason and then needing a DTR to restart the port.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.