Serial communications : Arduino not reacting

I'm currently working on a (big) project that uses lots of elements. The machine I'm developping is meant to be a tool for biology labs that study insect's behavior.

Since there are lots of inputs and outputs (9 servo SG90, 1 servo SG5010, and 12 relays as output, 9 thermistors, 1 DHT22, and a RTC clock as inputs), I'm using an Arduino Mega 2560. The Arduino is USB-linked to a computer, on wich Putty is running, in order for the user to send commands and receive data.

I've attached my code to this post. It is quite long, but a lot of it is repetition. (I've created and used functions as well as I could).

My problem is that, when I upload that code to the Arduino, I read data correctly (I see 9 different temperatures, the humidity, "door state" wich indicates the SG90's position, etc), but if I send an instruction from Putty, I see the Rx led blink, but nothing ever happens. No matter how short the instruction is (even if it's just one character).

But, if I upload a smaller code to the Arduino, that commands one single motor, for instance, or one relay, etc, then it works without problem (for every elements).

As I don't truly understand the problem, I find it difficult to find a solution... I figured it could be a synch problem between the computer and the Arduino, and the commands sent are lost in the process. Either that, or it's an alimentation problem, but then again, the Arduino is powered by a computer's alim (5 V, and up to 20 A...), the servo's are detached after beeing used so they don't use power, and the 12 relays are on 2 plates so it shouldn't use too much power either.

I've tried several things (quite randomly) to make it work. I changed the communications' speed (I've set it to 9600 bauds, 115200 bauds, 57600 bauds), it didn't work. I tried to set a time out as well (I tried 500 ms, 1000 ms, 100 ms, 2000 ms, also quite randomly :roll_eyes: ), it didn't work either. I tried the set delays between each if-else conditions, no better results.

I'm lost here, I don't understand what happens after the Arduino receive the commands (it does, the Rx blink...), why the command is lost every time, and I don't know what to do to fix it :sob:

I would appreciate some help !

Projet_Integrateur.ino (13.2 KB)

First step is to learn how to use the for-loop to shrink your code right down.

Second step is to get rid of delay() calls - look at the BlinkWithoutDelay example first, you simply
cannot have blocking code in something that has lots of functionality like this, everything needs to
run together.

In particular calling delay() after available() is an efficient way to lose serial input - it makes no sense at all.

  Serial.print (
  
  Serial.print ("Humidity level : ");
  Serial.println (OS_hum);
  Serial.println ('\n');
  
  Serial.println (ventilatorState);
  Serial.print (inducing_pop);
  Serial.println (inducing_activity);
  previous_time_1 = actual_time; 
  }

There is something very wrong with this section of code. Does it even compile ?

MarkT: You suggest I replace delay() by the millis(), when I need it? (I put the delay after available to let the buffer time to be loaded with all the characters. If I don't, the Arduino might start testing the conditions before all the caracters are in the buffer, like if I write do1 in Putty, the Arduino might start testing the condition with only "do", for instance, no ?)

UKHeliBob : Yep, sorry about that, I forgot that line... Now I've deleted it, and yes it compiles correctly.

maverick169:
(I put the delay after available to let the buffer time to be loaded with all the characters.

That is not a reliable or convenient way to receive data. Have a look at the examples in Serial Input Basics - simple reliable ways to receive data without blocking and without any need for delay()

In the program in your Original Post you seem to have about 300 lines of code in loop(). 20 lines would be more sensible - and all the other stuff in functions that can each be tested on its own. Have a look at Planning and Implementing a Program

You have a lot of libraries included in your program. It is possible that they are not all compatible with each other.

...R

I know my code is messy, I'm not very experimented... I will rewrite it entirely, following your advices. Thanks for the links !

I will remove all the delays as well (or as much as possible), and check if it is working on Thursday / Friday.

If anyone have any other ideas about why the commands are not functionning, please keep answering :smiley:

So, I changed the code, following your tutorial, and started with a simple "print version" on an Arduino uno, to test it.
My code is in attachment.

The problem now is that the arduino only takes into account the first number that the user types in. For instance, if I send the command "23", the Arduino will execute the command 2.
I used the endMarker as showed in your tutorial, and the Arduino execute the command only if I type in the endMarker.

I could simply replace all the numbers after 9 by other ASCII characters (so that I would only have one character per command), but I would still have a problem with my "composed command".

Thakns for your help !

testANT.ino (7.27 KB)

maverick169:
So, I changed the code, following your tutorial, and started with a simple "print version" on an Arduino uno, to test it.
My code is in attachment.

As you have not said, I am assuming you are referring to Serial Input Basics tutorial

You have not attacked the problem in the way that my tutorial intends. Just use my recvWithStartEndMarkers() function in your code and elsewhere in your code do things if (newData == true).

Don't muck about adding stuff into functions that already work. Complex programs are much easier to develop if the different parts are in separate functions that can be tested separately.

It is also very much easier to help if you are using code that I am familiar with - i.e. without your modifications.

...R

I was referring to Serial Input Basics, indeed ^^

When I use your recvWithStartEndMarkers (), the result is the same, so I'm guessing the problem is in my exeCmd - exeCompCmd (). (I tried to use your code without any change, and juste replace the showData - showParsedData () by exeCmd, since I need to use the content of the message and not just print it.

So my problem is that if I write "<25,14>" in the terminal, using your recvWithStartEndMarkers (), Arduino would react as if I wrote "<2>". Here is my exeCompCmd ()

void exeCompCmd () {
  
  if (*messageFromPC == '23') {
      inducingActivity = integerFromPC ; }
  else if (*messageFromPC == '24') {
      inducingPop = integerFromPC; }
      
  else if (*messageFromPC == '25') {
      W_Temperatures[0] = integerFromPC ; }

(and so on)

(The full code is in attachment, again)

testANT2.ino (6.63 KB)

if (*messageFromPC == '23')It's not illegal, but it is unusual

This is not right

else if (*messageFromPC == '10') {

First, there is no need for the asterisk
Second, the single quotes imply a character and you have 2 characters
Third, you can't compare cstrings with ==

To compare cstrings you need to use strcmp()

If you just want to examine a single character you could do

if (messageFromPC[0] == '1') {

...R

Ooook, now the "test version" works, thanks a lot robin ! :smiley:
I will try it on the device and say the result asap.

Thank you all for your help.

(Final test code in attachment)

testANT2.ino (6.97 KB)