Need help with Serial Commnication

I am trying to get a pc to control leds that are contected to a TLC5940 but am having trouble getting getting the arduino to take the input and then change the led colour.

I currently have this so far and am not getting the results i was expecting. I would send “RGB;255;255;255#” to the arduino then it should split each part between ; and then assign the values to r & g & b so that I can send them to the TLC5940 but all I keep getting is symbols and not numbers.

Is someone able to help with this, i have been rewriting this code all week and is starting to get on my nerves. Never thought making something with Serial and a TLC5940 would be so hard.

#include "Tlc5940.h"
#include <string.h>

#define MAX_STRING_LEN  20

char sz[20];

char* r; char* g; char* b;
int rval; int gval; int bval;
int stoploop = 0;

void setup()
{
 Tlc.init();
 Serial.begin(9600);
 
 Serial.println("Setup awaiting");
}

void loop(){
int i = 0;
stoploop = 0;

   while (Serial.available() > 0 && stoploop == 0) {
       sz[i] = Serial.read();
       
       if (sz[i] == '#') {
         stoploop = 1;
         //Serial.println("End of data"); 
       }
       
       //Serial.print(i);
       //Serial.print(":");
       //Serial.print(sz[i], BYTE);
       //Serial.print("\t");
       
       ++i;
   }
   
   if (stoploop == 1) {
     r = subStr(sz, ";", 2);
     g = subStr(sz, ";", 3);
     b = subStr(sz, ";", 4);

     rval = int(r);
     gval = int(g);
     bval = int(b);
     
     Serial.print("R:");
     Serial.print(r);
     Serial.print("\t");
     Serial.print("G:");
     Serial.print(g);
     Serial.print("\t");
     Serial.print("B:");
     Serial.print(b);
     Serial.print("\t");
   
     //Tlc.set(0, int(rval));
     //Tlc.set(1, int(gval));
     //Tlc.set(2, int(bval));
   
     //Tlc.update();
     
     stoploop = 0;
   }
}

// Function to return a substring defined by a delimiter at an index
char* subStr (char* str, char *delim, int index) {
   char *act, *sub, *ptr;
   static char copy[MAX_STRING_LEN];
   int i;

   // Since strtok consumes the first arg, make a copy
   strcpy(copy, str);

   for (i = 1, act = copy; i <= index; i++, act = NULL) {
      //Serial.print(".");
      sub = strtok_r(act, delim, &ptr);
      if (sub == NULL) break;
   }
   return sub;

}

Your code never puts a zero byte on the end of the string 'sz'. Maybe you need something like this when you've just read in a '#':

sz[i] = '\0';

I have change the following code:

       if (sz[i] == '#') {
         stoploop = 1;
         //Serial.println("End of data");
       }

To:

       if (sz[i] == '#') {
         sz[i + 1] = '\0';  //Change add 0 byte to end of array
         stoploop = 1;
         //Serial.println("End of data");
       }

I still have the same problem with symbol charaters and not text.

I have managed to work out that the problem is somewhere in this bit of code but am not sure what is wrong. Maybe someone else will have better luck at finding it than me.

   if (stoploop == 1) {
     r = subStr(sz, ";", 2);
     g = subStr(sz, ";", 3);
     b = subStr(sz, ";", 4);

     rval = int(r);
     gval = int(g);
     bval = int(b);
     
     Serial.print("R:");
     Serial.print(r);
     Serial.print("\t");
     Serial.print("G:");
     Serial.print(g);
     Serial.print("\t");
     Serial.print("B:");
     Serial.print(b);
     Serial.print("\t");
   
     //Tlc.set(0, int(rval));
     //Tlc.set(1, int(gval));
     //Tlc.set(2, int(bval));
   
     //Tlc.update();
     
     stoploop = 0;
   }
}

// Function to return a substring defined by a delimiter at an index
char* subStr (char* str, char *delim, int index) {
   char *act, *sub, *ptr;
   static char copy[MAX_STRING_LEN];
   int i;

   // Since strtok consumes the first arg, make a copy
   strcpy(copy, str);

   for (i = 1, act = copy; i <= index; i++, act = NULL) {
      //Serial.print(".");
      sub = strtok_r(act, delim, &ptr);
      if (sub == NULL) break;
   }
   return sub;

}

Genzolis,

I think your problem will be solved… or at least improved… if you change

   while (Serial.available() > 0 && stoploop == 0) {
       sz[i] = Serial.read();
       ...
       }

to

   while (stoploop == 0) {
       if (Serial.available() > 0)
       {
         sz[i] = Serial.read();
         ...
       }
     }

What’s happening now is that the first byte of your string arrives and is correctly placed into the buffer. Then the while loop executes again, but Arduino is so fast compared to Serial that the second byte has not yet arrived. So Serial.available() is 0 and the while loop terminates. loop() exits and re-enters a few times. Eventually the second byte appears, but it overwrites the first one (because i is reset to 0 each time loop() is re-entered).

Mikal

I have given it a go and still end up with symbols. I have decided to rewrite it again from scratch, so I can build it bit by bit.

Thanks

Genzolis, (a) I think you were nearly there; don't give up, and (b) I think your problem is probably that sz doesn't contain what you think it does when you begin parsing it. You should Serial.print that out. Post your latest and we can take a look.

M