Read .txt file sent from PC

Status
Not open for further replies.
Hi everyone!

I'm trying to send and read a text file from PC to the teensy. I already created a software on the PC with VS and I managed to send the file to the teensy.
The file is like this:

aaaaaaaaaaaaaaaaa
ddddddddddddddddd
aaaaaaaaaaaaaaaaa


Code:
void scenario ()
{
  line[16];
  for (int y = scen_min; y < scen_max; y++)
  {
    if(buffer[y] != ' ')
    {
      line[y] = buffer[y];
    }   
  }
  /*for(int y = scen_min; y < scen_max; y++)
  {
    TIME += line[y];
  }
  Serial.print(TIME);*/
  Serial.print(line);
  /*Serial2.println("SCENOK");
  Serial.println("SCENOK");*/
}

With this piece of code I managed to print all the lines from the file.
But when I try in the loop to show one line at a time, I can't make it show one line at a time, it only shows the last line all the time.
I'm new in coding, so if anyone could help me it would be very nice.

Thanks,
Jonathan
 
You're right, sorry

Code:
char buffer[1000];  //buffer for serial data recive from PC
bool scenario1 = false;
char line[17];
int scen_min = 0;
int scen_max = 18;
 void setup()
{

  /*--get module gsm wake up-----*/

  pinMode(FONA_KEY, OUTPUT);
  digitalWrite(FONA_KEY, PIN_ON);  //
  delay(200); //POUR REVEILLER LE GSM FAUT FAIRE UN HIGH DE 200MS SUR LE PIN FONA_KEY
  digitalWrite(FONA_KEY, PIN_OFF);    //
  /*-------CONFIG SERIAL PORT FOR GSM-------*/
  fonaSerial->begin(4800);
  /*-------CONFIG SERIAL PORT FOR GPS-------*/
  Serial4.begin(4800);
  /*-------CONFIG SERIAL PORT FOR PC--------*/
  Serial2.begin(9600);
  Serial.begin(9600);

}/* FIN  setup */

void loop()
{
 while (Serial2.available () > 0)
  {
    ReadDataPC (Serial2.read ());
  }
 if (scenario1)
  {
    scenario1 = false;

    Serial2.println("SCENOK");
    //Serial.println("SCENOK");
  }
while (Serial4.available () > 0) {
    ReadTimeGPS(Serial4.read ());  //mise a jour des heures minutes et secondes temps reel gps
  }
}
void DataPC()
{
  Serial.println(buffer[0]);
  switch (buffer[0])  // premier case de data recu determine dans quelle cas de config on se trouve
  {
    case '0':   //reception des trame configuration
      configuration();
      break;

    case '1': // cas ou l'operateur n'a pas recu le premier sms on renvoye a nouveau
      Send_msg(_message);
      break;

    case '2': // cas ou le congig gsm a echué on refait une tentative
      config_gsm ();
      break;

    case '3': // cas ou le congig gps a echué on refait une tentative
      config_gps ();
      break;

    case '4': // cas ou le congig gps a echué on refait une tentative
      config_servo ();
      break;

    case '5': // reception scenario1
      scenario1 = true;
      scenario();
      break;

    case '6': //reception scenario2
      scenario2 = true;
      break;

    case '7': // reception scenario3
      scenario3 = true;
      break;

    case '8': // start
      Serial2.println( "STARTOK");
      startOK = true;
      Serial.println( "STARTOK");
      start_enrg = true;
      break;

    case '9': // stop
      Serial2.println( "STOP");
      Serial.println( "STOP");
      startOK = false;
      compteur10 = 0;
      break;

    case 'A': // SI LE PC REPOND PRESENT IL PEUX ENVOYER LES ENREGISTREMENTS
      send_enrg = true;
      Serial.println("RECU A");
      break;

  }
}
void configuration()
{
  config_servo();
  config_gps();
  config_gsm();
  Serial2.println( "GSM_OK");
  Serial2.println("MSG_SEND");
  Serial2.println("SERVO_OK");


}

void scenario ()
{
  line[16];
  for (int y = scen_min; y < scen_max; y++)
  {
    if(buffer[y] != ' ')
    {
      line[y] = buffer[y];
    }   
  }
  /*for(int y = scen_min; y < scen_max; y++)
  {
    TIME += line[y];
  }
  Serial.print(TIME);*/
  Serial.print(line);
  /*Serial2.println("SCENOK");
  Serial.println("SCENOK");*/
}
void config_gps ()
{
  Serial2.println("GPS_OK");
  Serial.println("GPS_OK");
}
void config_gsm ()
{

  if (!fona.begin(*fonaSerial))
  {
    Serial2.println( "GSM_FAIL");
    Serial.println( "GSM_FAIL");
  }
  else
  {
    Serial2.println( "GSM_OK");
    Serial.println( "GSM_OK");
    Send_msg( _message );
  }
}
void config_servo ()
{
  XreSmdr = buffer[46];
  Serial.println(buffer);

  for (int x = indexservo_min; x < indexservo_max; x++)
  {

    if (buffer[x] == '1')
    {
      Serial.print(   "modex_resmdr= " + XreSmdr + buffer[x]);  //FAUT RAMPLCER SERIAL PRINT PAR LA COMMANDE SEND SUR BUS CAN
    }

  }
}

void Send_msg(char *  message )
{
  char  nu_telefone[14];
  for (int i = 1; i < 15; i++)
  {
    if (buffer[i] != ' ')
    {
      nu_telefone[i - 1] =  buffer[i];
    }
  }

  fona.sendSMS(nu_telefone, message);
  Serial2.println("MSG_SEND");
  Serial.println("MSG_SEND");
}

What's the next step to make the the teensy read the lines on the loop?
 
that cannot be the whole code
as the function calls
ReadDataPC (Serial2.read ());
ReadTimeGPS(Serial4.read ());
is missing the functions in the code

if it is DataPC then you are missing to fill the buffer before call
ex in loop
it should be something like this (with rxPointer as a global int):

Code:
while (Serial2.available () > 0)
{
    byte rxByte = Serial2.read();
    buffer[rxPointer++] = rxByte;
    if (rxByte == '\n') {
        DataPC();
        rxPointer=0; // reset pointer to make it ready for the next data line
    }
}

there is the
Serial.readBytesUntil(character, buffer, length)
but that blocks the main "thread" until it have read all characters
so it should be avoided.
 
Last edited:
Sorry, you right. I forgot the ReadDataPc() ;)

Code:
void ReadDataPC (const byte inByte)
{
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;
  switch (inByte)
  {

    case '\n':   // end of text

      buffer [input_pos] = '\n';  

    
      DataPC();

      // reset buffer  next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return


      break;

    default:
      

      if (input_pos < (MAX_INPUT - 1))
        buffer [input_pos++] = inByte;
      break;

  }

}
 
I think you are missing to compare with if(buffer[y] != '\n') in:
(corrected with \n)
Code:
void scenario ()
{
  line[16];
  for (int y = scen_min; y < scen_max; y++)
  {
    if(buffer[y] != '\n')  // <--- corrected here
    {
      line[y] = buffer[y];
    }   
  }
  /*for(int y = scen_min; y < scen_max; y++)
  {
    TIME += line[y];
  }
  Serial.print(TIME);*/
  Serial.print(line);
  /*Serial2.println("SCENOK");
  Serial.println("SCENOK");*/
}
 
sending the whole file should not be a problem
unless the file is very big
and the input buffer of the Serial port gets overflowed by incoming data.
 
No, the file is not that big. I can see that the file is well received when i print it on the serial. I get this:

5aaaaaaaaaaaaaaaaa5

5ddddddddddddddddd5

5aaaaaaaaaaaaaaaab

The "5" is "case" number on teensy. But when I print it on the loop, I only get this:

aaaaaaaaaaaaaaaab

Can't manage to show the other lines
 
Code:
void scenario ()
{
  //line[16]; // don't know what this should be doing so I comment it out
  for (int y = scen_min; y < scen_max; y++)
  {
    if(buffer[y] != '\n')
    {
      line[y] = buffer[y];
    }
    else
    {
         line[y] = 0x00; // null character is needed for the Serial.print 
         break; // end the for loop
    }   
  }
  /*for(int y = scen_min; y < scen_max; y++)
  {
    TIME += line[y];
  }
  Serial.print(TIME);*/
  Serial.print(line);
  /*Serial2.println("SCENOK");
  Serial.println("SCENOK");*/
}
 
Last edited:
was thinking the serial print was smarter but:

the Serial.print don't take byte array as input (only String)

so the proper print of array buffer would be:
Code:
for (int i = 0; buffer[i] != '\n'; i++) Serial.print(buffer[i]);
Serial.print('\n'); // or Serial.println();


but maybe just do it directly in the first loop:
Code:
void scenario ()
{
  //line[16]; // don't know what this should be doing so I comment it out
  for (int y = scen_min; y < scen_max; y++)
  {
    if(buffer[y] != '\n')
    {
      line[y] = buffer[y]; // use for other things?
      Serial.print(buffer[y]);
    }
    else
    {
         line[y] = 0x00; // null character is good to have in end of string
         Serial.print('\n');
         break; // end the for loop
    }   
  }
  /*for(int y = scen_min; y < scen_max; y++)
  {
    TIME += line[y];
  }
  Serial.print(TIME);*/
  //Serial.print(line);
  /*Serial2.println("SCENOK");
  Serial.println("SCENOK");*/
}
 
It doesn't work... when I use '\n' it doesn't even print on the loop, when I use ' ', well it prints but only the last line.
Isn't there a function to send it read the first line again?

Sorry, but I'm really new to this...... this is a university project, complex one...
 
@ luni Yes they do,
But the Serial.print function don't take array as the input (have checked the Print.cpp source)
which is really dumb as you are forced to use the formatted printf which is little overkill in this situation
and using Serial.write also is overkill as it need the size parameter

why just not have a simple Serial.print that takes array as input and the only requirement is that the array ends with null char.

this is why I always did my libraries from scratch.
 
maybe it's safer to use
println()
instead of
print('\n')

as your terminal program maybe listens for \r\n

and the println includes \r\n
 
@ luni Yes they do,
But the Serial.print function don't take array as the input (have checked the Print.cpp source)
which is really dumb as you are forced to use the formatted printf which is little overkill in this situation
and using Serial.write also is overkill as it need the size parameter

why just not have a simple Serial.print that takes array as input and the only requirement is that the array ends with null char.

this is why I always did my libraries from scratch.


I'm probably missing something but

Code:
void setup()
{
    while(!Serial);

    char test[] = "Hello World\n";
    Serial.print(test);
//....

prints "Hello World" here.
 
but then when I'm looking at Print.h file
there is this

size_t print(const char s[])

which seems to take a array buffer
 
Still not working, still only printing the last line... and yes probably my program uses \r\n, because it's a windows forms...
Any other idea?
 
I find this unexplained (with the first only working):

Code:
 void setup()
{
  Serial2.begin(9600);
  Serial1.begin(9600);
  Serial.begin(9600);
}
void loop()
{
  while (Serial.available () > 0)
  {
    Serial.write('0');
    Serial.write(Serial.read());
  }
  while (Serial1.available () > 0)
  {
    Serial1.write('1');
    Serial1.write(Serial1.read());
  }
  while (Serial2.available () > 0)
  {
    Serial2.write('2');
    Serial2.write(Serial2.read());
  }
}

I am using triple usb serial,
can anyone verify what the different Serial Serial1 Serial3 and so on is used for
 
this simplified example works for me
Code:
char buff[1000];  //buffer for serial data recive from PC

char line[17];
int scen_min = 0;
int scen_max = 18;
 void setup()
{
  Serial.begin(9600);
}/* FIN  setup */

void loop()
{
  ReadDataPCTask();

}
void ReadDataPCTask()
{
  while (Serial.available() > 0)
  {
    char inByte = Serial.read();
    //static char input_line[scen_max];
    static unsigned int input_pos = 0;
    switch (inByte)
    {
      case '\n':   // end of text
        buff[input_pos] = '\n';  
        DataPC();
        // reset buffer  next time
        input_pos = 0;
        break;
  
      case '\r':   // discard carriage return
        break;
  
      default:
        if (input_pos < (scen_max - 1))
          buff[input_pos++] = inByte;
        break;
    }
  }
}
void DataPC()
{
  //Serial.println(buffer[0]);
  switch (buff[0])  // premier case de data recu determine dans quelle cas de config on se trouve
  {
    case '5': // reception scenario1
      //scenario1 = true;
      scenario();
      break;
  }
}
void scenario ()
{
  for (int y = scen_min; y < scen_max; y++)
  {
    if(buff[y] != '\n')
    {
      line[y] = buff[y]; // use for other things?
      //Serial.print(buffer[y]);
    }
    else
    {
         line[y] = '\r';
         line[y+1] = '\n';
         line[y+2] = 0x00; // null character is good to have in end of string
         //Serial.println();
         break; // end the for loop
    }   
  }
  Serial.print(line);
}
 
i can send this line without any problem ($0a is the \n in the terminal program that I use)
Code:
5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaasbaaaa$0a5aaabaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a5aaaaaaaaaa$0a

which returns
terminaloutput.png
 
Code:
char line[17];
int scen_min = 0;
int scen_max = 18;
......

void scenario ()
{
  line[16];
  for (int y = scen_min; y < scen_max; y++)

line holds 17 characters, but putting in 18. Buffer overflow as well as no space for the terminating zero that is needed.
 
Status
Not open for further replies.
Back
Top