Go Down

Topic: *char hex naar int (Read 368 times) previous topic - next topic

haubke

hallo allemaal,

ik ben bezig met een project, ik krijg seriele data binnen, Deze laad ik in een String. Uit deze string haal ik bepaalde karakters uit. Deze karakters moeten een hexadecimaal getal voorstellen. Nu heb ik een heel raar probleem. als ik de volgende data binnen krijg gaat het goed,

data in FF 00 00

uit 255 , 0 , 0.

data in 00 FF 00

uit 0,3480,0 ??

als ik 0000FF binne krijg is mijn output
0,255,255  ??



Code: [Select]
   
roods[0] =data.charAt(Index+1);
              roods[1] =data.charAt(Index+2);
              Serial.println(roods);

              groens[0] =data.charAt(Index+3);
              groens[1] =data.charAt(Index+4);
              Serial.println(groens);

              blauws[0] =data.charAt(Index+5);
              blauws[1] =data.charAt(Index+6);
              Serial.println(blauws);
 
              rood =  x2i(roods);
              groen = x2i(groens);
              blauw = x2i(blauws);
                
                //rood = strtoul(roods, NULL, 16);
                //groen = strtoul(groens, NULL, 16);
                //blauw = strtoul(blauws, NULL, 16);
                Serial.println(rood);
                Serial.println(groen);
                Serial.println(blauw);


zoals jullie hierboven kunnen zien heb ik het ook geprobeerd met strtoul(); , maar hier krijg ik dezelde output.  Overigens moet ik er wel bij vertellen dat ik op een maple mini werk. zou eigenlijk niet uit moeten maken maar toch. nergens anders in de code maak ik gebruik van deze chars of strings.

dit is de code die het omzet naar een int,
Code: [Select]

int x2i(char *s)
{
 int x = 0;
 for(;;) {
   char c = *s;
   if (c >= '0' && c <= '9') {
      x *= 16;
      x += c - '0';
   }
   else if (c >= 'A' && c <= 'F') {
      x *= 16;
      x += (c - 'A') + 10;
   }
   else if (c >= 'a' && c <= 'f') {
      x *= 16;
      x += (c - 'a') + 10;
      }
   else break;
   s++;
 }
 Serial.println(x);
 return x;
}


Heeft iemand enig idee wat er mis gaat?.

bedankt,

Jantje

Zo ophet eerste zicht zie ik niks fout.
Ik zou serial.print(ln)'s toevoegen om meer te weten te komen.
Met vriendelijke groet
Jantje
Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

cartoonist

Als ik dit definieer:

Code: [Select]

char roods[3], groens[3], blauws[3] ;
int rood, groen, blauw;
String data;
int Index =-1;

void setup() {
Serial.begin(9600);
data = "00FF00";
}


en jouw loop en functie  gebruik krijg ik gewoon 00, 255, 00 als resultaat.
misschien had je de array's te klein gedefinieerd ?
You do not need a new P.C., you need a new O.S.  Linux is free, safe, easy, fast and reliable.

nicoverduin

Zoals Cartoonist al zegt heb je wel 3 bytes neer gezet als ontvangende string? Daarnaast moet je zorgen dat het 3e byte een '\0' is. Anders gaat het mogelijk alsnog fout.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

haubke

halle allemaal,

allereerst dankjewel voor jullie reactie,
Idd ergens in mijn programma zou er een derde Char* bij moeten komen. maar ik schrijf er maar twee naar toe 0 en 1 wel te verstaan.
ik heb ze dan ook als volgt gedefinieerd:

char roods  [1]="";
char groens [1]="";
char blauws [1]="";

De printlines heb ik er ook al tussen gezet, Daar kan ik ook zien dat er een character bij komt, Maar deze declareer ik nergens en schrijf er ook niks naartoe.

geen idee waar deze extra karakter vandaan komt. nu heb ik voor het gemak maar even de functie aangepast en zelf geschreven. deze is als volgt:

Code: [Select]

int x2i(char *s)
{int x=0;
int y =0;
       if (s[0] >= '0' && s[0] <= '9') {
          x = (s[0] - '0') * 16 ;
       }
         else if (s[0] >= 'A' && s[0] <= 'F') {
          x = (s[0] - 'A') + 10;
          x=x*16;
           }
 if (s[1] >= '0' && s[1] <= '9') {
      y = s[1] - '0';
   }
   else if (s[1] >= 'A' && s[1] <= 'F') {
      y = (s[1] - 'A') + 10;
     
   }
 x = x + y;
 Serial.println(x);
 return x;
}
[\code]

Nu krijg ik wel de goede waarde(dec)  terug, Alleen blijf ik nog steeds het probleem hebben dat er zomaar karakters bij komen. nu komen er zelfs twee bij.

dit is de string:
# 0C0286

output is:

0C    024F    86

Waar die 4F vandaan komt mag joost weten.

Wat mij opvalt is dat de waarde die ik de eerste keer ingeef:

laten we zeggen 001122 voor het gemak, kloppen deze waardes. 00 11 22  Maar als ik daarna nog een keer een waarde ingeef bijv  44 55 66 , krijg ik deze output in de char array ,   44 5522 66, Deze extra characters komen dus van de waarde die ik daarvoor binnen gekregen heb, en deze wordt dan daar bij geschreven? :s

ik heb geen idee meer.

Wordt er bij een character array niet automatisch een '/0' verwacht?



nicoverduin

Dat klopt ook allemaal wel, maar op het moment dat je ze behandeld als een string moet er een '\0'aan het einde staan. vandaar de 3e karakter.
Verder, weet ik niet of jij van puzzelen houd? Ik wat minder dus is het handig als je de hele code hier neerzet. Zo kan ik er weinig mee.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

Jantje

#6
Feb 20, 2015, 05:43 pm Last Edit: Feb 20, 2015, 05:44 pm by Jantje
Verder, weet ik niet of jij van puzzelen houd? Ik wat minder dus is het handig als je de hele code hier neerzet. Zo kan ik er weinig mee.
+1
Code: [Select]
char roods  [1]="";
dit is fout. Heb ik al eens uitvoerig uitgelegd op dit forum. char gaat met ' en string met "
Jantje
Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

haubke

hallo nico,

ik zal alle code neerzetten wat hier mee te maken heeft, Alle code die ik heb geschreven is veel te lang. de \0 karakter had ik er bij staan maar heb ik er weer uit gehaald.
Code: [Select]

int rood = 0;
int blauw = 0;
int groen = 0;

char roods  [2]="";
char groens [2]="";
char blauws [2]="";

String data ="";

// hier haal ik de data binnen van de seriele poort en sla deze op in de String data
while(Serial1.available()) // check if the esp is sending a message
           {  
           char c = Serial1.read();
           data+=c;
           }

             Index = Find("#");
             roods[0] =data.charAt(Index+1);
             roods[1] =data.charAt(Index+2);
             Serial.println(roods);

             groens[0] =data.charAt(Index+3);
             groens[1] =data.charAt(Index+4);
             Serial.println(groens);

             blauws[0] =data.charAt(Index+5);
             blauws[1] =data.charAt(Index+6);
             Serial.println(blauws);

             rood =  x2i(roods);
             groen = x2i(groens);
             blauw = x2i(blauws);

               Serial.println(rood);
               Serial.println(groen);
               Serial.println(blauw);

int x2i(char *s)
{
int x=0;
int y =0;
      if (s[0] >= '0' && s[0] <= '9') {
         x = (s[0] - '0') * 16 ;
      }
        else if (s[0] >= 'A' && s[0] <= 'F') {
         x = (s[0] - 'A') + 10;
         x=x*16;
          }
       if (s[1] >= '0' && s[1] <= '9') {
           y = s[1] - '0';
       }
         else if (s[1] >= 'A' && s[1] <= 'F') {
          y = (s[1] - 'A') + 10;
    
        }
x = x + y;
Serial.println(x);
return x;
}


overigens krijg ik de extra karakters alleen bij groens.

String en char array is niet hetzelfde toch? ik dacht namelijk dat alleen bij een string er automatisch een '\0' achter gezet wordt. en een char array puur en alleen karakters zijn.

jantje, ik zal eens kijken of dit wel helpt. Het zou zomaar mogelijk zijn, Maar als dit niet kan waarom geeft de compiler dan geen error?.

bedankt voor de hulp

bedankt voor de hulp


PieterB

Heb je iets aan deze draad over 'Conversion from int/hex to char'  http://forum.arduino.cc/index.php?topic=103418.0

nicoverduin

Tja hoe je het wend of keert een char array heeft nu eenmaal een \0 nodig. Doe je dat niet gaat println gewoon door tot dat er een '\0' is gevonden. Daarnaast zou ik heel voorzichtig zijn met Strings. Ze zijn een prachtige oorzaak van geheugen fragmentatie. En de processoren kennen geen garbage collection.
Daarnaast wat doet dit?
Code: [Select]

Index = Find("#");

Of eigenlijk waar kijkt deze Find in? Moet er niet data. voor staan? Ik neem tenminste aan dat je in data zoekt naar het # teken?

Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

haubke

Hallo,

Ik zal vanavond als ik weer thuis ben nog eens spelen met het \0 karakter. Inderdaad als je op een "arduino" programmeert kan ik de data.find() functie gebruiken. Maar ik werk met arduino code op een stm32 (maple mini styyuuclone).  En daar werkt de find functie niet op. Ik heb een eigen functie moeten maken. Deze zoekt standaard in de data.  In ieder geval hartelijk dank voor de hulp, ik laat nog iets weten of het gewerkt heeft.

nicoverduin

Ken die STM implementaties. Misschien een reden om het "Arduino" concept los te laten? MBED is ook nog een optie. Tegenwoordig zijn er al vrij veel boards in gedefinieerd en er is ook offline compilatie mogelijk via EM::Blocks.
Ik weet wel dat ze weer bezig zijn met de maple implementaties om die verder uit te bouwen, maar krijg een beetje de indruk dat dat nog niet echt op schiet. Maar String is een class die je eigenlijk beter links kan laten liggen tenzij je een string gelijk creƫert op de maximale lengte. Nu breid je hem uit en zal hij elke keer opnieuw geheugen alloceren als er een karakter bijkomt. En dat is knap inefficiƫnt en ondanks de (20K dacht ik) gaat dat gegarandeerd een keer mis.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

haubke

Mischien is het inderdaad beter om een andere compiler te pakken. Maar het gemak van arduino is ook wel fijn.

Helaas ben ik ook nog niet zo ver dat ik zo alle registers kan setten die ik nodig heb om bijv. Seriele poort te gebruiken enz enz. 

   De data die ik binnen krijg is altijd het zelfde. Alleen ben ik nog niet volledig klaar ben met het programma is de lengte nog "variabel" . de data die binnen komt komt van een esp8266. Dus ik kan kiezen char array of een string. Maar heb gekozen voor een string waarna ik na ontvangst de data uit ga halen.


nicoverduin

Dat je niet gelijk het hele programma in die ESP gooit en dan eentje nemen met minimaal 3 GPIO pinnen.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

Go Up