Sorry if this has been asked, I did search and read a lot and learned a lot but nothing that really answered my question.
I am useing an Ardunio Pro Mini, Software Serial on pins 4 and 5. String of data comes in every 1 second. The UART is being used to communicate with a LCD panel that just will not work with SS for whatever reason.
Example incoming Data,
123,25.5,30,26.0,456,25.5,60,26,224,25.5,30,22.0,123,25.5,30,26.0,0,0,0,0,13.9,28.9,25,90;
The ";" is my end of packet character. It never seems to be reached (i'm turning on pin 13 LED when the incoming character is ';'). The exact same code works fine on the regular UART so I am guessing that the SS can't read the entire string fast enough before the next one comes in thus the end ";" character is never reached.
Is one second enough time to clear the buffer?
I can't post code publicly but if you want to take a look I can send it to you in a PM if I can attach it or email it to you.
It might just be crappy coding, Although I try to learn from you guys
Ok, here is the function in question. I had a chance to try it once, the LED never flickers, but might be too fast to see. I didn't get a chance to try some delays.
The other issue is that the entire program might have to much going on, so it's possible doing a sketch with just this one thing might work and I'm no further forward. That is why I would rather someone look at the entire program.
#include<SoftwareSerial.h>
#define EOP ';'
SoftwareSerial SSerial(4,5); // RX, TX
int Data[25];
int c;
int Voltage;
int Percent[4];
int iTemp;
int TD;
int Low;
int High;
int Ff;
int Fg;
int Fb;
int Fa;
byte Index = 0; //Data index
void setup()
{
// put your setup code here, to run once:
SSerial.begin(9600);
}
void loop()
{
digitalWrite(13,LOW);
ReadTankData();
}
void ReadTankData() // DIGITAL
{
if(SSerial.available())
{
c = SSerial.read();
if(c >= '0' && c <= '9')
{
iTemp = iTemp * 10 + (c - '0');
}
else if(c == ',') // Record Data and move to next index
{
Data[Index] = iTemp;
Index++;
iTemp = 0;
}
else if(c == EOP) // Record data and exit loop
{
digitalWrite(13,HIGH);
Data[Index] = iTemp;
Index = 0;
iTemp = 0;
Percent[0] = Data[2];
Percent[1] = Data[6];
Percent[2] = Data[10];
Percent[3] = Data[14];
Ff = Data[3];
Fg = Data[7];
Fb = Data[11];
Fa = Data[15];
TD = Data[16];
Voltage = Data[20];
Low = Data[22];
High = Data[23];
}
}
}
// End ReadData()
If SoftwareSerial couldn't read fast enough, that it couldn't read one character before another arrived, it would be useless. Your problem lies elsewhere.
Now that I see your excerpted code, I can't see anything wrong (except you are not handling decimal points).
Possibly the problem is in the code you don't post.
The SoftwareSerial buffer is 64 bytes. That means you can muck around doing other stuff, as long as you empty the buffer before it reaches 64 bytes.
Your string quoted above is 90 bytes. Thus, if you spend a lot of time doing something else, the buffer may fill up by the time you go to read from it.
It's possible that some other part of the code is casing to slow even more like you say. If I use the code on the Hardware UART everything works. Also, everything else works in my code, it just shows 0's for all that data because the ";" is never reached so the data doesn't update to current values.The LED never turns ON. I'll do more testing.
OK , using the code i posted above, I commented out the line that turns the LED OFF, so it should at least turn the LED on if the EOP is reached. at least once. The LED never comes on. So either it is getting over written by the next line coming in or ??? I'm stumped. And nothing else in the way, just that snippet.
OK, now that I have corrected my test sketch (I did call out the baud rate in the complete sketch) I now get a flicker on the LED about every second, so the EOP is being reached.
I'll have to really go over my code, I'm just not seeing where the hangup is. Getting late so tomorrow. It's really pretty simple for that part, it supposed to gather all the data then update a touchscreen after it reads all the data. I look at it after a few hours of sleep.
Robin2:
Try using one of the examples in serial input basics to receive all of the data before you try to parse any of it.
...R
Thanks for the info, nice read but I think that is what I am doing with the EOP is it not? I don't handle the data until the ";" is received, and that's the whole issue. It's not being received.
Next,
Here is another test file that does not work.
#include<SoftwareSerial.h>
#define EOP ';'
SoftwareSerial SSerial(4,5); // RX, TX
int Data[25];
int c;
int Voltage;
int Percent[4];
int iTemp;
int TD;
int Low;
int High;
int Ff;
int Fg;
int Fb;
int Fa;
byte Index = 0; //Data index
void setup()
{
// put your setup code here, to run once:
SSerial.begin(9600);
}
void loop()
{
digitalWrite(13,LOW);
doFirstCall();
//ReadTankData();
}
void doFirstCall()
{
ReadTankData();
}
void ReadTankData() // DIGITAL
{
if(SSerial.available())
{
c = SSerial.read();
if(c >= '0' && c <= '9')
{
iTemp = iTemp * 10 + (c - '0');
}
else if(c == ',') // Record Data and move to next index
{
Data[Index] = iTemp;
Index++;
iTemp = 0;
}
else if(c == EOP) // Record data and exit loop
{
digitalWrite(13,HIGH);
Data[Index] = iTemp;
Index = 0;
iTemp = 0;
Percent[0] = Data[2];
Percent[1] = Data[6];
Percent[2] = Data[10];
Percent[3] = Data[14];
Ff = Data[3];
Fg = Data[7];
Fb = Data[11];
Fa = Data[15];
TD = Data[16];
Voltage = Data[20];
Low = Data[22];
High = Data[23];
}
}
}
// End ReadData()
The only difference is the serial function is being called from within another function. And that seems to break it. My test LED no longer flickers like it does without the added function call.
It is being called this way in my main sketch as well so I will do some altering on it and see what happens.
Jassper:
Thanks for the info, nice read but I think that is what I am doing with the EOP is it not? I don't handle the data until the ";" is received, and that's the whole issue. It's not being received.
There is a lot of stuff in your ReadTankData() which is not in my examples - so why not try to do it the simple way first. That way you can send the raw data back to the PC as a check on the correct reception.
Also the line ReadTankData; will not work without its ()
Robin2:
Also the line ReadTankData; will not work without its ()
...R
Yeah, I corrected it after posting it. Sorry about that.
I will try your suggestions, I see what your saying, I'm just asking the questions so I can better understand what is really happening. As stated before if I switch this all over the hardware UART, everything works as is. So it may be that SS is just to slow for this application, or at least I will need to handle it differently.
I stripped my test code down to just the following. The LED will flicker as I would expect about once per second. If I set the delay to anything over 2, the the LED either will not flicker at all, or it will blink erratically.
#include<SoftwareSerial.h>
#define EOP ';'
SoftwareSerial SSerial(4,5); // RX, TX
int Data[25];
int c;
int Voltage;
int Percent[4];
int iTemp;
int TD;
int Low;
int High;
int Ff;
int Fg;
int Fb;
int Fa;
byte Index = 0; //Data index
void setup()
{
// put your setup code here, to run once:
SSerial.begin(9600);
}
void loop()
{
if(SSerial.available())
{
c = SSerial.read();
if(c >= '0' && c <= '9')
{
iTemp = iTemp * 10 + (c - '0');
}
else if(c == ',') // Record Data and move to next index
{
Data[Index] = iTemp;
Index++;
iTemp = 0;
}
else if(c == EOP) // Record data and exit loop
{
digitalWrite(13,HIGH);
Data[Index] = iTemp;
Index = 0;
iTemp = 0;
Percent[0] = Data[2];
Percent[1] = Data[6];
Percent[2] = Data[10];
Percent[3] = Data[14];
Ff = Data[3];
Fg = Data[7];
Fb = Data[11];
Fa = Data[15];
TD = Data[16];
Voltage = Data[20];
Low = Data[22];
High = Data[23];
}
}
delay(2);
digitalWrite(13,LOW);
}
// End ReadData()
To me that don't sound right but, I still have LOTs to learn. I will also try a new Arduino Pro Mini as soon as they arrive just in case something is wrong with this one.
I will start playing with your examples now, like you said, I may need to just get all the data in first, then play with it later.
This code works for me. This program will print a message "Software serial begin" if you reset the micro when you hook up your usb to ttl adapter. If you don't see that you need to find out what is wrong with your usb to ttl setup, I think.
/*
read software serial
convert to decimal, place in array and print array contents at end of record
non blocking
test string:
123,25.5,30,26.0,456,25.5,60,26,224,25.5,30,22.0,123,25.5,30,26.0,0,0,0,0,13.9,28.9,25,90;
*/
#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(10, 11); // RX, TX
const uint16_t buffSize = 25; // size as necessary
uint16_t inBuff [ buffSize ] = { 0 };
uint16_t buffIndex = 0; // keep track of array entries
uint8_t inChar;
uint16_t inVal;
void setup()
{
Serial.begin ( 9600 );
Serial.println ( F ( "Hardware serial begin." ) );
SoftSerial.begin ( 9600 );
SoftSerial.println ( F ( "Software serial begin." ) );
} // setup
void loop ()
{
while ( SoftSerial.available () > 0 )
{
inChar = SoftSerial.read ();
switch ( inChar )
{
case ';': // end of record, enter last data
if ( buffIndex < ( buffSize -1 ) )
{
inBuff [ buffIndex ] = inVal;
}
// print out array content for demo
SoftSerial.println ( F ( "End of data, print out array: " ) );
for ( byte x = 0; x <= buffIndex ; x++ )
{
SoftSerial.println ( inBuff [ x ] );
}
buffIndex = 0; // reset vars for next record
inVal = 0;
break;
case '0' ... '9': // capture the numeric ascii input and convert to decimal
inVal = inVal * 10 + inChar - '0';
break;
case ',': // field data complete, update array
if ( buffIndex < ( buffSize -1 ) )
{
inBuff [ buffIndex ] = inVal;
buffIndex++; // set for next var
}
inVal = 0; // reset
break;
} // switch
} // while
} // loop
Jassper:
And by the way, your test examples - the EXACT same result.
Your code in Reply #15 is not the simple code from my example. It would help me to help you if you use my exact code and post the version that you use that does not give you the correct answer. I need to see which of my examples you have used and exactly how you have used it.
If that shows an error in my code then I will be able to update my example.