RS232 informatie splitsen over meerdere variabelen

Ontwerpen en programmeren

Postby walbeek » Fri Apr 15, 2011 12:00 am

Hoi allemaal,

Ik wil een PIC programmeren met Flowcode. Via RS232 (en een X-port) ontvang ik informatie die er ongeveer zo uitziet:

1,71,1,POLL,1297418487,0x00

Deze tekst moet worden gesplitst over meerdere variabelen.
Het eerste getal (1) moet bijvoorbeeld in variabele PROTOCOL.
Daarna volgt een komma en dat betekend dat de volgende informatie begint, in dit geval een ID (71) wat in de variabele ID moet.

Ik moet dus de komma detecteren en dan verder in het programma stappen. Ik heb hierbij wat hulp nodig.

Ik kan RS232 lezen als BYTE of als STRING.
IK denk dat BYTES makkelijker is in dit geval?

De PIC is bezig met andere dingen en kan niet alleen naar RS232 kijken. Is het mogelijk dat ontvangst eerst een interupt genereerd?

Als ik een komma ontvang, hoe kan ik die detecteren?

Ook ontvang ik een woord in de informatie, in dit geval POLL.
Dat betekend een bepaalde actie voor de PIC, in dit geval informatie versturen. Hoe kan ik dit woord (POLL) controleren?
Ik moet dan vergelijken met een stringvariabele neem ik aan?

Dan volgt er een groot getal, een tijd in seconden. Dat past volgens mij helemaal nergens in. Hie kan ik dat splitsen en verdelen over meerdere INT variabelen?

Het laatste getal is een checksum, dat begint altijd met 0x en dan volgt het checksum getal zelf. in het voorbeeld 00. Dat is de uitkomst van XOR op alle bytes samen. Maar dat is een probleem voor later.

Kan iemand mij een zetje in de goede richting geven? Ik hoor graag jullie tips om dit aan te pakken.

Rinie
walbeek
 
Posts: 191
Joined: Thu Jan 02, 2014 3:27 pm

Postby arjen h. » Fri Apr 15, 2011 12:00 am

Er zijn vele wegen die naar Rome gaan en voor dit probleem zijn er ook wel meerdere oplossingen...

Om verder te gaan op BYTES; ik neem aan een array van bytes (karakters).

Deze kun je stuk voor stuk tegen een integercode testen.
Een '1' is 31 hexadecimaal en is dus 49 decimaal.
Het zou dus iets kunnen worden van "if (data[0] == 49) then ..."
De komma is 2C hexadecimaal en dus 44 decimaal.
Zo kun je stuk voor stuk verder testen.

Is dit de bedoeling?


Voor het opdelen van 1297418487 in meerdere integers zul je een truc moeten uithalen. Ten eerste moet je een array hebben van voldoende integers. Dan moet je een keuze maken wat de maximale waarde is die je in een integer wil stoppen. Je zou kunnen kiezen voor maximaal 3 karakters, dat is dus 999.

Een stukje pseudocode hoe het in C er ongeveer uit zou kunnen zien.

int intjes = new int[10];  // dit is de array, alle elementen initialiseren op 0int integerindex = 0;  // arraytellerint karakter = 0;  // bepalen of we 3 karakters hebben gehadint index = 0;  // index in de data-arraywhile (data[index] != 44){  intjes[integerindex] = intjes[integerindex] * 10;  intjes[integerindex] = intjes[integerindex] + data[index] - 48;  karakter = karakter + 1;  if (karakter == 3)  {    karakter = 1;    integerindex = integerindex + 1;  }  index = index + 1;}


In het geval van 1297418487 heb je dus uiteindelijk:
  intjes[0] = 129  intjes[1] = 741  intjes[2] = 848  intjes[3] = 7


Omdat in intjes[3] maar 1 karakter is opgeslagen moet bij het verder verwerken rekening worden gehouden met het gewicht van de andere elementen. injes[2] zijn nu namelijk geen duizendtallen maar tientallen.



Het ontvangen van data op de RS232 zou een interrupt moeten kunnen genereren. Hier moet een vlaggetje in een van de SFR registers voor gezet worden.


Eerst maar eens horen of je hier verder mee kunt, daarna borduren we verder.
Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1306
Joined: Thu Jan 02, 2014 10:40 am

Postby buckfast_beekeeper » Mon Apr 25, 2011 12:00 am

Rinie,

Heb je zelf controle over wat je µC gaat uitspuwen? Dan zou ik het iets anders aanpakken.

Ik zou de scheiding al niet maken met een , of een . Zo hou je de mogelijkheid open om float getallen te versturen. Meestal wordt in zulk een situatie ; gebruikt.

Een woord zou ik ook niet gebruiken. Vervang POLL bijvoorbeeld door 1. Scheelt 3 te verzenden bytes.

Controleren op byte waarde is ook eenvoudiger dan een volledige string controleren. POLL is niet gelijk aan poll. Het is ook niet gelijk aan Poll. De ASCII waarde van P is 65, p is 97.

Als einde van je regel gebruik je standaard een CR of ASCII 13.

De seconden worden deze verstuurd van uit de µC of vanuit de PC? indien het getal verzonden wordt door de µC, dan zou ik verkiezen om digit per digit in ASCII door te sturen. Aan de PC-zijde een string concatenatie tot je ; tegenkomt en dan omzetten naar een float.
buckfast_beekeeper
 
Posts: 820
Joined: Thu Jan 02, 2014 3:27 pm


Return to Microcontrollers

Who is online

Users browsing this forum: No registered users and 1 guest

cron