Teensy 2+ cutting strings in the middle when sending over UART

Status
Not open for further replies.

srusha

Active member
Hello, I am sending a very long string to seeedstudio gprs modem (v.2) and the string is cut in the middle, I tried every single transmit baud for the connection and it always reappears.

when using the same code with arduino mega it works great.

Any ideas what to do?

p.s.
my query string looks something like

AT+HTTPPARA=\"URL\",\"http://x.x.x.x/system/ping.php?id=1&data=1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;1;2;9;0;2;3;5;1;
 
You have a couple of extra spaces inside that long parameter string, are they correct?
 
mlu: these extra spaces were not in the actual code,

here is the full test code:
it is based on the cooking hacks code: http://www.cooking-hacks.com/index....orials/arduino-gprs-gsm-quadband-sim900#step8

#include <Time.h>
#include <Streaming.h>

time_t t;


int8_t answer;
int onModulePin= 9;
HardwareSerial Uart = HardwareSerial();
char data[512];
int data_size;

char aux_str[100];
char aux;
int x = 0;


void setup(){
Uart.begin(19200);
pinMode(onModulePin, OUTPUT);
Serial.begin(19200);

Serial.println("Starting...");
power_on();

delay(3000);
sendATcommand("AT+IPR=19200","ok",2000);

while (sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 2000) == 0);

// answer = sendATcommand("AT+IPR=?", "OK", 10000);
sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
sendATcommand("AT+SAPBR=3,1,\"APN\",\"internet\"", "OK", 2000);
// sendATcommand("AT+SAPBR=3,1,\"USER\",\"\"", "OK", 2000);
// sendATcommand("AT+SAPBR=3,1,\"PWD\",\"\"", "OK", 2000);
answer= sendATcommand("AT+SAPBR=2,1", "+SAPBR: 1,1", 2000);
if(answer!=1)
while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) == 0)
{
delay(5000);
}


}
void loop(){
// Initializes HTTP service

answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
if (answer == 1)
{
// Sets CID parameter
answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
if (answer == 1)
{
// Sets url
answer = sendData();
if (answer == 1)
{
// Starts GET action
answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 10000);

if (answer == 1)
{
x=0;

sprintf(aux_str, "AT+HTTPREAD=%d,100", x);
if (sendATcommand2(aux_str, "+HTTPREAD:", "ERROR", 30000) == 1)
{
data_size = 0;
while(Uart.available()==0);
aux = Uart.read();
do{
data_size *= 10;
data_size += (aux-0x30);
while(Uart.available()==0);
aux = Uart.read();
Serial.print(aux);
}
while(aux != 0x0D);


if (data_size > 0)
{
while(Uart.available() <= data_size);
Uart.read();

for (int y = 0; y < data_size; y++)
{
data[x] = Uart.read();
Serial.print( data[x]);
x++;
}
data[x] = '\0';
}
else
{
Serial.println("Download finished");
}
}
else if (answer == 2)
{
Serial.println("Error from HTTP");
}
else
{
Serial.println("Error getting the url");
data_size = 0;
}

Serial.print("Data received: ");
Serial.println(data);
}
else
{
Serial.println("Error getting the url");
}
}
else
{
Serial.println("Error setting the url");
}
}
else
{
Serial.println("Error setting the CID");
}
}
else
{
Serial.println("Error initializating");
}

sendATcommand("AT+HTTPTERM", "OK", 5000);
}

void power_on(){

uint8_t answer=0;

// checks if the module is started
answer = sendATcommand("AT", "OK", 2000);
if (answer == 0)
{
// power on pulse
digitalWrite(onModulePin,HIGH);
delay(3000);
digitalWrite(onModulePin,LOW);

// waits for an answer from the module
while(answer == 0){
// Send AT every two seconds and wait for the answer
answer = sendATcommand("AT", "OK", 2000);
}
}

}


int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout){
int i;
uint8_t x=0, answer=0;
char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( Uart.available() > 0) Uart.read(); // Clean the input buffer

Uart.println(ATcommand);


x = 0;
previous = millis();

// this loop waits for the answer
do{
if(Uart.available() != 0){
response[x] = Uart.read();
x++;
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));
Serial.println(response);
return answer;
}



int8_t sendATcommand2(char* ATcommand, char* expected_answer1,
char* expected_answer2, unsigned int timeout){

uint8_t x=0, answer=0;
char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( Uart.available() > 0) Uart.read(); // Clean the input buffer

Uart.println(ATcommand); // Send the AT command


x = 0;
previous = millis();

// this loop waits for the answer
do{
if(Uart.available() != 0){
response[x] = Uart.read();
x++;
// check if the desired answer 1 is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
// check if the desired answer 2 is in the response of the module
if (strstr(response, expected_answer2) != NULL)
{
answer = 2;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));
Serial.println(response);
return answer;
}





int8_t getClock(){
int second, minute, hour, dayOfWeek, dayOfMonth, month, year;
int timeout=1000;
uint8_t x=0,y=0, answer=0;
char response[100];
unsigned long previous;
answer=0;
memset(response, '\0', 100); // Initialize the string

delay(100);

while( Uart.available() > 0) Uart.read(); // Clean the input buffer

Uart.println("AT+CCLK?"); // Send the AT command

y=0;
x = 0;
previous = millis();

// this loop waits for the answer

x=0;
do{
if(Uart.available() != 0){
response[x] = Uart.read();
x++;
// check if the desired answer is in the response of the module
if(x >37)answer=1;
}
// Waits for the asnwer with time out
}
while((answer== 0) && ((millis() - previous) < timeout));



year=(response[20]-48)*10+(response[21]-48);
month=(response[23]-48)*10+(response[24]-48);
dayOfMonth=(response[26]-48)*10+(response[27]-48);
hour=(response[29]-48)*10+(response[30]-48);
minute=(response[32]-48)*10+(response[33]-48);
second=(response[35]-48)*10+(response[36]-48);


setTime(hour,minute,second, dayOfMonth,month,year);
Serial.println(response);
return answer;
}


int8_t sendData(){
char* expected_answer1="OK";
unsigned int timeout=5000;
int i;
uint8_t x=0, answer=0;
char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( Uart.available() > 0) Uart.read(); // Clean the input buffer





Uart.println("AT+HTTPPARA=\"URL\",\"http://212.1.208.94/system/ping.php?id=1&data=1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;0;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;0;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;0;0;1;2;0;0;0;1;0;10;1;0;1;2;0;0;0;1;0;10;0;0;1;2;0;0;0;0;1;5;5;-1461633991;0;0;0;0;0;1;1;1970;\"");



x = 0;
previous = millis();

// this loop waits for the answer
do{
if(Uart.available() != 0){
response[x] = Uart.read();
x++;
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));
Serial.println(response);
return answer;
}
 
Last edited:
I tried to reproduce this problem. Obviously I can't run that large program as-is, because I do not have this particular Arduino shield.

So I tried to do the best I could with the info and code you provided. I copied that long print line into a minimal program. I removed the extra spaces. The exact code I used for testing is attached below.

I connected pin 3 on the Teensy++ to the RX pin on a FTDI TTL-232R-3V3 cable, and of course I connected their grounds together. I ran the Seyon terminal emulator to view the data as received by the FTDI cable.

uart_srusha.jpg

As you can see in this screenshot (click for full size), the FTDI cable receives the entire string.

I'm not sure what else I can do to try to help. Any ideas?
 

Attachments

  • uart_srusha.ino
    598 bytes · Views: 149
I tried to reproduce this problem. Obviously I can't run that large program as-is, because I do not have this particular Arduino shield.

So I tried to do the best I could with the info and code you provided. I copied that long print line into a minimal program. I removed the extra spaces. The exact code I used for testing is attached below.

I connected pin 3 on the Teensy++ to the RX pin on a FTDI TTL-232R-3V3 cable, and of course I connected their grounds together. I ran the Seyon terminal emulator to view the data as received by the FTDI cable.

View attachment 865

As you can see in this screenshot (click for full size), the FTDI cable receives the entire string.

I'm not sure what else I can do to try to help. Any ideas?

You think the problem might lay in the receiving end?I can try to connect the tx/rx to arduino and check what it receives..

I am using 1.0.4, do you think that might be the problem?

by the way, what buffer do you use? (rx/tx buffer for the hwserial)
 
You think the problem might lay in the receiving end?

I do not know. This simple test seems to suggest the transmission is ok, but it's entirely possible there's a subtle bug causing corrupt transmission with that more complex program. I simply do not have enough info to really guess where the problem is.

I can try to connect the tx/rx to arduino and check what it receives..

Can you use Serial.end() on the Arduino board, so it's USB chip works similarly to the FTDI cable? Then you can use it to just listen to Teensy++ -> modem signal.

I am using 1.0.4, do you think that might be the problem?

by the way, what buffer do you use? (rx/tx buffer for the hwserial)

I'm using Arduino 1.0.5 with Teensyduino 1.15 installed.

I tested with the code attached to message #6 above. I used this TTL-232R-3V3 cable.
 
I tried a simpler program, with same setup, both code and serial window in the following image fE1as6o.jpg

I think the problem might lay with the rx buffer of the teensy? what do you think?

by the way, thanks for all the help
 
In the image it is shown that every other 3rd or 4th "request" in cut in the middle, at random places.

the code itself sends the long query and reads the response. thats all.

also, something a bit interesting, whenever I added a delay after the trasmit it screwed everythings up, when I put it after the "while" loop that reads everything (actually at the end of loop() ) it always cut the string, and always in the same place,
 
Can you maybe recommend me on a gprs lib that would make everything easier..? (the arduino official lib doesn't support sim900)
 
Perhaps the problem is a bug in the code that attempts to receive a reply?

Code:
  // this loop waits for the answer
  do{
    if(Uart.available() != 0){
      response[x] = Uart.read();
      x++;
      // check if the desired answer is in the response of the module
      if (strstr(response, expected_answer1) != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while((answer == 0) && ((millis() - previous) < timeout));

If the modem is echoing the command characters, perhaps this code is writing too much data to the response[] array? The array is 100 characters long, but this code does not check to make sure it's not writing past the end of the array (and thus corrupting whatever comes later in memory).

Perhaps add a check for the array size, like this:

Code:
      response[x] = Uart.read();
      if (x < sizeof(response)-1) x++;

You could also increase the size of the array. Even though properly limiting x so it doesn't go beyond the end of the array could keep your program from crashing, if your intention is to receive something after the end of the echoed command, not store data after the array fills up obvious won't work.

Be mindful that your variable x is 8 bits, so it can't go beyond 255. Your string appears to be at least 400 characters long. You'll almost certainly have to change x to larger integer.

I took a quick look at the Cooking Hacks code. It does not seem to have any very long strings. They still should have checked the value of x to not write beyond the end of their array. But those 100 character arrays were probably anticipated to be much larger than any data.
 
Last edited:
I dont understand how you cant read the image, the quality you see is poor? or do you just cant access the image?
 
Status
Not open for further replies.
Back
Top