Arduino : String of data in een Array krijgen

Plaats reactie
helmuteke
Premium Member
Premium Member
Berichten: 526
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 25 keer

ik heb deze vraag ook al gepost in de arduino forums maar krijg niet direct een respons daar

effe uitleggen wat ik heb

ik heb een
char buffer[516];

welke gevuld is met data
als ik de buffer weergeef krijg ik dit

0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255

wat ik nu zou wensen is een array waarbij

int data[0] = 0
int data[1] = 0
int data[3] = 255
int data[4] = 255

enzo voort

wat ik al geprobeerd heb is dit

Code: Selecteer alles

for( str = strtok_r(buffer, "," ,&p);
        str;
        str = strtok_r(NULL, "," , &p)
        )
        {
         Serial.println(str);
       // data[i] = str;
       i++; 
        }
maar dan krijg ik fout van
standv3:66: error: invalid conversion from 'char*' to 'long int'

kan iemand me op de goede weg brengen
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16609
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 564 keer
Bedankt: 759 keer
Contacteer:

Ik ken d'er niks van, maar al Googlen'd vind ik dit: http://stackoverflow.com/questions/9072 ... ring-array
Gebruikersavatar
Joe de Mannen
Elite Poster
Elite Poster
Berichten: 5339
Lid geworden op: 22 feb 2005, 12:46
Uitgedeelde bedankjes: 487 keer
Bedankt: 556 keer

zonder de definities van de variabelen is het haast onmogelijk om te helpen. Maar de foutmelding zegt het al:
standv3:66: error: invalid conversion from 'char*' to 'long int'
Er zit dus volgens mij een fout in het declareren van de variabelen, je zal ergens een char-array in een long int willen zetten of omgekeerd en dat gaat niet.

de fout zit ook 'ongeveer' in lijn 66 van je code. dat helpt bij het zoeken. (edit: beter gezegd: de fout wordt ontdekt op ongeveer lijn 66)

J.
Ik ben alleen verantwoordelijk voor mij eigen uitspraken, niet voor wat anderen ervan maken of aan toevoegen...
gm123
Elite Poster
Elite Poster
Berichten: 1106
Lid geworden op: 08 maa 2009, 22:27
Uitgedeelde bedankjes: 67 keer
Bedankt: 119 keer

Bestaan uw chars enkel uit 0 en 255? Zo ja kan je gewoon iets in deze aard doen:

Code: Selecteer alles

int data[516];

for(int i = 0; i < sizeof(buffer); i++){
   if(buffer[i] == 0)
      data[i] = 0;
   else
      data[i] = 255;
}
Gebruikersavatar
Joe de Mannen
Elite Poster
Elite Poster
Berichten: 5339
Lid geworden op: 22 feb 2005, 12:46
Uitgedeelde bedankjes: 487 keer
Bedankt: 556 keer

als je maar 2 waarden hebt is er een boolean misschien een betere keuze, maar daar ging de vraag niet over zeker :)

J.
Ik ben alleen verantwoordelijk voor mij eigen uitspraken, niet voor wat anderen ervan maken of aan toevoegen...
helmuteke
Premium Member
Premium Member
Berichten: 526
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 25 keer

het kunnen alle waardes zijn tussen 0 en 255
gm123
Elite Poster
Elite Poster
Berichten: 1106
Lid geworden op: 08 maa 2009, 22:27
Uitgedeelde bedankjes: 67 keer
Bedankt: 119 keer

Een variant dan:

Code: Selecteer alles

int data[516];

for(int i = 0; i < sizeof(buffer); i++){
   for(int j = 0; j <= 255; j++){
      if(buffer[i] == j)
         data[i] = j;
   }
}
Zeer inefficiënt, maar wel snel geïmplementeerd.
helmuteke
Premium Member
Premium Member
Berichten: 526
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 25 keer

denk niet dat het zo simpel is

uw code hou geen rekening met de comma's alsook gaat deze cijfer per cijfer bekijken

2
5
5
,

ik denk toch dat de volledige string eerst moet gesplit worden
gm123
Elite Poster
Elite Poster
Berichten: 1106
Lid geworden op: 08 maa 2009, 22:27
Uitgedeelde bedankjes: 67 keer
Bedankt: 119 keer

Dus die string 0,255,0,... is de ascii representatie van jouw buffer? Dan nog gaat mijn manier werken, het ging niet zozeer over mijn implementatie maar over de werkwijze. Zie ook wat honda hieronder schreef, hij heeft gelijk over wat hij zegt van sizeof(), maar het idee blijft hetzelfde. Niet vergeten dat een char niet meer is dan een nummer. Dit gaat dus bv perfect:

Code: Selecteer alles

int a = ',';
int b = 'b';
En wat ook perfect gaat:

Code: Selecteer alles

char a = ',';

if(a == ',')
   //doe iets
Dus: je loopt je buffer af en doet (indien nodig) de conversie van ascii naar decimaal en steekt deze waarde in je data array. Wanneer je een komma tegen komt negeer je die.
Laatst gewijzigd door gm123 30 jan 2014, 19:01, in totaal 5 gewijzigd.
Gebruikersavatar
honda4life
Elite Poster
Elite Poster
Berichten: 5659
Lid geworden op: 03 jan 2010, 21:42
Locatie: 127.0.0.1
Uitgedeelde bedankjes: 186 keer
Bedankt: 315 keer

gm123 schreef:Bestaan uw chars enkel uit 0 en 255? Zo ja kan je gewoon iets in deze aard doen:

Code: Selecteer alles

int data[516];

for(int i = 0; i < sizeof(buffer); i++){
   if(buffer[i] == 0)
      data[i] = 0;
   else
      data[i] = 255;
}
Dit is op de goede weg.
Ben geen fan van het Arduino programmeerplatform, maar wel van AVR Studio dus licht anders.

Enkele opmerkingen:
int = 2 bytes. voor 0-255 heb je slechts 1 byte nodig nodig zonder tekenbit. Dit is dus een uint8_t of een char is ook mogelijk.
sizeof() gaat de waadre teruggeven als aantal bytes. Wat wil zeggen dat je "i" buiten bereik van de array gaan.

Maar zoals hierboven ook staat, snap totaal niet wat je wil bereiken.
Je bent aan het smossen met geheugen dat het niet schoon is lijkt me...
✂ – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
helmuteke
Premium Member
Premium Member
Berichten: 526
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 25 keer

Zal dan even uitleggen wat de bedoeling is

ik heb een softwareprogramma waarmee ik licht sequenties programmeer
deze converteer ik met een python scriptje naar een txt

elke lijn is een stap ik het lichtprogramma waarbij elk kanaal staat beschreven

vb

255,255,255,0,128 etc . . .
kanaal 1 = 255
kanaal 2 = 255
kanaal 3 = 255
kanaal 4 = 0
kanaal 5 = 128
etc...

deze gegeneerde file schrijf ik weg naar een SD kaart welke ik in een arduino shield steek

wat nu mijn sketch doet is de File open en lijn per lijn uitlezen.

Wat ik wil bereiken is dat als deze een lijn uitleest , deze de date plaatst in een array zodat ik de juiste lichten kan aansturen

dus
data[0] = 255 = kanaal 1
data[1] = 255 = kanaal 2
data[2] = 255 = kanaal 3
etc . . .


wat ik met mijn code heb

Code: Selecteer alles

for( str = strtok_r(buffer, "," ,&p);
        str;
        str = strtok_r(NULL, "," , &p)
        )
        {
         Serial.println(str);
        data[i] = *str;
       i++; 
        }
is dat ik dus deze 'string' van data kan splitsen in de benodigde waardes maar ik ze niet kan plaatsen in de array voor 1 of andere reden


de andere declaraties zijn
char *str;
int i=0 ;
char buffer[516];
long data[516];

hopelijk brengt dit waar mee verduidelijking.
gm123
Elite Poster
Elite Poster
Berichten: 1106
Lid geworden op: 08 maa 2009, 22:27
Uitgedeelde bedankjes: 67 keer
Bedankt: 119 keer

Ok, ik denk dat ik het snap. Stel dat er "255," in jouw buffer zit. Als ik het goed begrijp ziet je buffer er dus zo uit:

Code: Selecteer alles

buffer[0] = '2';
buffer[1] = '5';
buffer[2] = '5';
buffer[3] = ',';
En je wil dit omzetten naar de decimale waarde 255. Een mogelijke oplossing is als volgt. De char sequentie 2 5 5 kan je omzetten naar een decimale voorstelling met een simpele berekening: 2 * 10^2 + 5 * 10^1 + 5 *10^0 = 255. Hiervoor moet je wel eerst de conversie doen van ascii naar decimaal, want een ascii voorstelling van het cijfer 2 komt niet overeen met de decimale waarde 2.

Nu kan er ook "50," in je buffer zitten, waardoor je niet begint bij 10^2 maar bij 10^1. Om te weten bij welke macht van tien je moet vertrekken kijk je gewoon hoe verweg de komma staat in relatie tot de huidige positie. Stel dat we nu op de nulde plaats in de buffer zitten, dan staat de komma 3 plaatsen verder. Dit wil zeggen dat het getal dat je wil converteren een getal tussen 0 en 999 is, ofwel in de orde van 10^(3-1) = 100. Wat je dan doet is:

Code: Selecteer alles

ascii_to_decimal(buffer[0]) * 10^2 + ascii_to_decimal(buffer[1]) * 10^1 + ascii_to_decimal(buffer[0]) 10^0
Dus vertrekkend van 10^2 en dan altijd de macht aftellen tot 0. In het geval van "50," vertrek je bij 10^1. Dus je vertrekt bij 10^(plaats van de komma - 1).

ascii_to_decimal kan je zelf simpel schrijven, en het aflopen van de buffer doe je met een lus waarbij je telkens telt tot je een komma vindt, en dan verder gaat na de komma.

Heb mijn best gedaan om de oplossing die ik in mijn hoofd heb zitten neer te schrijven. Ik ben er vrij zeker van dat ze werkt, hopelijk begrijp je waar ik naartoe wil. :-D
Laatst gewijzigd door gm123 30 jan 2014, 19:18, in totaal 1 gewijzigd.
Gebruikersavatar
honda4life
Elite Poster
Elite Poster
Berichten: 5659
Lid geworden op: 03 jan 2010, 21:42
Locatie: 127.0.0.1
Uitgedeelde bedankjes: 186 keer
Bedankt: 315 keer

Hoe schrijf je je data naar de kaart.
is 255 nu 3 karakters '2' '5' '5', en een scheidingsteken ',' om het leesbaar te houden?
Of doe je het raw als "getal" '0xFF waarbij je dus een databestand krijgt en geen tekstbestand'?
Is de laatste methode ook een optie voor je? Je zal veel geheugen besparen en denk een hoop ellende.

Wat ze hierboven zeggen is mogelijk maar kan pakken beter met pointers.
Niet vergeten, bij een microprocessor moet je nadenken over geheugen (ram + code) en snelheid.
Met een computer steekt het niet op een kilobyte meer of minder of om wat extra ticks.

Edit: Welke arduino heb je, zodat ik een idee kan vormen of je er gaat komen met geheugen.
Laatst gewijzigd door honda4life 30 jan 2014, 19:28, in totaal 2 gewijzigd.
✂ – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
gm123
Elite Poster
Elite Poster
Berichten: 1106
Lid geworden op: 08 maa 2009, 22:27
Uitgedeelde bedankjes: 67 keer
Bedankt: 119 keer

honda4life schreef:Is de laatste methode ook een optie voor je? Je zal veel geheugen besparen en denk een hoop ellende.
Als het wegschrijven naar binair een optie is, is dat inderdaad een véél efficiëntere oplossing.
Gebruikersavatar
honda4life
Elite Poster
Elite Poster
Berichten: 5659
Lid geworden op: 03 jan 2010, 21:42
Locatie: 127.0.0.1
Uitgedeelde bedankjes: 186 keer
Bedankt: 315 keer

Nieuw idee.
Oké tekstbestand kan een goed idee zijn.
Waarom niet als volgt?
Vermoed dat je iets wil doen met RGB ofzo?
Hoe denk je dat aan te sturen? Je hebt maar een 3-tal PWM kanalen?
Wil je Soft PWM toepassen, dat kan bepalend zijn hoe je de data gaat verwerken, dan zou ik ook een buffer gebruiken.

Bestand met:
Kanaal,Rood,Groen,Blauw;
Je leest lijn per lijn rechtstreeks van de kaart. Steekt deze in een buffer of lees ze elke cyclus opnieuw uit van de kaart.
Heel flexibel lijkt me, weet niet welke performantie je verwacht? Wil je 1 x per msec of 1 x per sec schakelen is toch wel belangrijk.
✂ – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
helmuteke
Premium Member
Premium Member
Berichten: 526
Lid geworden op: 08 feb 2010, 15:36
Uitgedeelde bedankjes: 3 keer
Bedankt: 25 keer

nu het rgb verhaal is juist , maar niet met de 3 kanalen zoals u zegt

ik werk met RGBLED (chipsets zoals de ws2801) via de SPI bus , dus een datalijn , clocklijn en de juiste library's zoals Fastspi vb

wat ik doe met de RGB waardes is een functie genaamd color oproepen welke me een getal retourneert dat ik naar de spibus stuur , en waar ik ook een kanaalnr mee meestuur.
Gebruikersavatar
honda4life
Elite Poster
Elite Poster
Berichten: 5659
Lid geworden op: 03 jan 2010, 21:42
Locatie: 127.0.0.1
Uitgedeelde bedankjes: 186 keer
Bedankt: 315 keer

Welke arduino? Spreken we over seconden, milliseconden,...
Vermoed dat je toch ook wel vertraging wil tussen bepaalde effecten,... Je geeft echt weinig informatie hoor om je goed te kunnen helpen.
✂ – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
ubremoved_539
Deel van't meubilair
Deel van't meubilair
Berichten: 29849
Lid geworden op: 28 okt 2003, 09:17
Uitgedeelde bedankjes: 446 keer
Bedankt: 1985 keer

gm123 schreef:Ok, ik denk dat ik het snap. Stel dat er "255," in jouw buffer zit. Als ik het goed begrijp ziet je buffer er dus zo uit:

Code: Selecteer alles

buffer[0] = '2';
buffer[1] = '5';
buffer[2] = '5';
buffer[3] = ',';
Een strtok neemt nooit de delimiter mee op in het resultaat... er zal dus gewoon 255 in z'n buffer zitten.
gm123 schreef:En je wil dit omzetten naar de decimale waarde 255. Een mogelijke oplossing is als volgt. De char sequentie 2 5 5 kan je omzetten naar een decimale voorstelling met een simpele berekening: 2 * 10^2 + 5 * 10^1 + 5 *10^0 = 255.
Ow... waarom zo complex... gebruik gewoon de atoi() functie welke een character array omzet naar een integer.
Gebruikersavatar
honda4life
Elite Poster
Elite Poster
Berichten: 5659
Lid geworden op: 03 jan 2010, 21:42
Locatie: 127.0.0.1
Uitgedeelde bedankjes: 186 keer
Bedankt: 315 keer

da's inderdaad simpel met een pointer op te lossen.
Je zoekt de positie van de komma, bewaart deze.
Vervangt de komma door een '\0'
Doet de atoi,
Je zoekt de positie van de komma vanaf positie van vorige komma +1, bewaart deze,...
✂ – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
ubremoved_539
Deel van't meubilair
Deel van't meubilair
Berichten: 29849
Lid geworden op: 28 okt 2003, 09:17
Uitgedeelde bedankjes: 446 keer
Bedankt: 1985 keer

Ook het warm water opnieuw aan het uitvinden... wat je beschrijft is wat strtok() doet !
Gebruikersavatar
honda4life
Elite Poster
Elite Poster
Berichten: 5659
Lid geworden op: 03 jan 2010, 21:42
Locatie: 127.0.0.1
Uitgedeelde bedankjes: 186 keer
Bedankt: 315 keer

Dat is indedaad nog een beter idee.
Wel strtok_r gebruiken dan :wink:
✂ – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Plaats reactie

Terug naar “Development”