Parsing an ascii string to unsigned16 and unsigned8

hello guys

i,m trying to send some values to arduino in ascii and convert to values.

there will be 4 values one with the range of 0-512 and the other 3 with the range of 0-7.

unsigned16,unsigned8,unsigned8,unsigned8,

so i,m trying to find out how to parse an ascii string like :

-ascii : öa (it seems it those not show the values in here so i paste the hex ones so you can read them)
in hex it will be : hex: F6 01 07 00 04
where [F6 01][07][00][04] those will represent this values :
502 ,7 ,0 ,4

how can a parse the ascii incoming string in arduino to unsigned16,unsigned8,unsigned8,unsigned8,
so in the end i,ll get 3 uint8_t and 1 uint16 like : 502 ,7 ,0 ,4

thanks

Why are you using those weird, unprintable characters and not some ASCII characters that make sense?

You can use the strtok() function to gather the incoming data. Being that you know how much data you will be receiving, you can take the first two (F6 01) and combine them into a WORD.

An example using the Serial monitor.

char data[30] = {0}, output[10];
int A, A_1;
int B,C,D,d=0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if(Serial.available() > 0){
    char c = Serial.read();  // 200, 55, 1, 2, 3
    data[d] = c;
    d++;
    if(c == '\n' || c == ' '){
      A = atoi(strtok(data, ",")); // 200
      A_1 = atoi(strtok(NULL, ",")); //55
      B = atoi(strtok(NULL,",")); // 1
      C = atoi(strtok(NULL,",")); // 2
      D = atoi(strtok(NULL," ")); // 3
   
      sprintf(output, "%d,%d,%d,%d", (A + A_1),B,C,D);
      Serial.print(output); //255,1,2,3
     d = 0; 
    }
  }
}

Note: when you send the data, make sure you break up the first part. 512(16bit) = 256(8 bit) + 256(8 bit)

hello thanks for replies

@jremington it is ascii but somehow display like this when i copied ;D.

that,s why i put the hex F6 01 07 00 04 which are those bytes [246][1][7][0][4] and represent those values [502][7][0][4]
as they should be interpreted like unsigned16,unsigned8,unsigned8,unsigned8

@HazardsMind

thank you for the example i had a quick look but did not get the procedure i,ll study it a better thanks again.

This is what i,d like to do :

get a string via udp with 512 packects of 5 bytes(ascii) which will be like the ones i show. i can put a header and ending characters if it helps .

then split this big string into an array of 5 bytes and those 5 bytes convert them to 4 values of unsigned16,unsigned8,unsigned8,unsigned8

any ideas examples welcome i struggle parsing strings in arduino.

cheers

It is possible to send binary numbers using serial. If the number of bytes being sent was really an issue, you could send your message in 4 bytes. But I don't think that the number of bytes being sent is really the issue here.

Or you can send it using normal ascii text representation of numbers. Just send the string "503456", to be precise, the specific ascii characters '5' '0' '3' '4' '5' '6' . The first three is your big number and the last three are your small numbers. You can then convert these into your numbers using the standard functions to do it.

HI michinyon
thanks for your suggestion.

I need to send a maximum of 512 packets i thought of the 5 bytes in ecnoded ascii and then convert to its unsigned16,unsigned8,unsigned8,unsigned8 types as if i send the value itself like of 511 for the first it is 5 pieces but if i send a value of 1 then it will be 4 pieces so making the conversion will always have same data length in each packet . yes i,d like to send the minimum possible via udp so to get the fastest transmission.
in the end this values will control a adafruit 16x32 ledmatrix so the fastest in transmission the better. i,ll be using arduino mega and ethernet shield.

what are the standard functions you talk about to do those splitting routines ?

hello guys

I have been testing some things , i got one test working but seems slow.

This is what i,d like to do in the end in the fastest minimize way send a message like :

[HeadingByte][Lenght][ValueBytesx5]
so for example :
[$][5][012345678910111213141516171819202122232425]
then need to use header to know the message is correct delete it and get length byte which i guess i can get rid of it by knowing the length of the message - 1 ( header). Not sure what it,s fastest.

i got this code working as a start up.

#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>       
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 12);
unsigned int localPort = 10000;      // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
//////////////
#define MAX_DATA_ELEMENTS 100    // the maximum number of integers in one received string
int input[MAX_DATA_ELEMENTS];  // array that will hold the received integers

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  //Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    //Serial.print("Received packet of size ");
    //Serial.print(packetSize);
    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    //Serial.println("Contents:");
    //Serial.println(packetBuffer);
    //Serial.print("String To Int ");
    getValues(packetBuffer,input,MAX_DATA_ELEMENTS );
    for ( int i = 0; i <MAX_DATA_ELEMENTS; i++) {
    //analogWrite(analogInputs[i],input[i]);
   //Serial.print(input[i]);
   
   analogWrite(5,input[0]); //Test for the Analog Pin 5
    }
    //Serial.println();
    delay(2);
}
}
void getValues(char * str,int * values, int maxelements) {
 // function to parse the given string and populate the values integer array
 // maxelements is the number of elements in the given values array
 // Note: this version assumes that the string is properly formed (i.e. contains only integers seperated by commas)
 char *result = NULL;
 int index = 0;
 result = strtok( str, "," );
 while( (result != NULL) && (index < maxelements) ) {
	values[index++] = atoi(result);
	result = strtok( NULL, "," );
 }
}

but i would like to make some faster solution.

  • for example do the splitting without the need of using commas as this make the message almost double the size.
    -be able to extract or do a check with the heading and delete from string i saw some sub string function for only for string type.
    -get the separated 5 values per packet.
    -Maxsize will be 512 but idially this number will be determined but the length of the message.
    -Already with 100 is a bit slow.

what solutions can you propose ?

thank you in advance :wink: