Pages: [1]   Go Down
Author Topic: Hulp gezocht bij inlezen txt file  (Read 579 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hoi,

Ik ben al een tijd aan het stoeien en puzzelen met het inlezen van een .txt file die ik op een SD kaart heb staan.
Het inlezen gaat op zich goed, en met STRTOK() is het me zelf gelukt om de waardes tussen de comma's van elkaar te scheiden.
Maar, het probleem zit hem er in dat ik de waardes die ik heb ingelezen later wil kunnen gebruiken. En het lukt me niet om de waardes in een herbruikbare variabele te krijgen.

Dit is de sketch die ik gebruik. Een bewerk ReadLn voorbeeld.
Code:
#include <tinyFAT.h>
#include <avr/pgmspace.h>

byte res;
word result;
char textBuffer[81];
char *str;
char *p;
char* mashString[20];
int I;

const int  MAX_STRING_LEN = 60; // set this to the largest string
                                // you will process
char stringBuffer[MAX_STRING_LEN+1]; // a static buffer for computation and output

char *verboseError(byte err)
{
switch (err)
{
case ERROR_MBR_READ_ERROR:
return "Error reading MBR";
break;
case ERROR_MBR_SIGNATURE:
return "MBR Signature error";
break;
case ERROR_MBR_INVALID_FS:
return "Unsupported filesystem";
break;
case ERROR_BOOTSEC_READ_ERROR:
return "Error reading Boot Sector";
break;
case ERROR_BOOTSEC_SIGNATURE:
return "Boot Sector Signature error";
break;
default:
return "Unknown error";
break;
}
}

void setup() {
  // Initialize serial communication at 115200 baud
  Serial.begin(115200);
  Serial.println();
  // Initialize tinyFAT
  // You might need to select a lower speed than the default SPISPEED_HIGH
  res=file.initFAT();
  if (res!=NO_ERROR)
  {
    Serial.print("***** ERROR: ");
    Serial.println(verboseError(res));
    while (true) {};
  }

//  Serial.println("This demo will display a textfile called 'maisch.txt'");
//  Serial.println();
//  Serial.println("***** Send any character to start *****");
//  while (!Serial.available()) {};
  Serial.flush();
  Serial.println();
  Serial.println();
 
  if (file.exists("maisch.txt"))
  { 
    I=0;
    res=file.openFile("maisch.txt", FILEMODE_TEXT_READ);
    if (res==NO_ERROR)
    {
      result=0;
      while ((result!=EOF) and (result!=FILE_IS_EMPTY))
      {
        result=file.readLn(textBuffer, 80);
        if (result!=FILE_IS_EMPTY)
        {
          if (result==BUFFER_OVERFLOW)
            Serial.print(textBuffer);
          else
//           Serial.println(textBuffer);
           strncpy(stringBuffer, textBuffer, MAX_STRING_LEN); // copy source string
           Serial.println(stringBuffer);                      // show the source string
 
           for( str = strtok_r(stringBuffer, ",", &p);        // split using comma
           str;                                          // loop while str is not null
           str = strtok_r(NULL, ",", &p)                 // get subsequent tokens
           )
         {
          mashString[I] = str;
//          Serial.print(I);
          Serial.print("Name: ");
          Serial.print(" :  ");
          Serial.println(mashString[I]);
//          Serial.println(str);         
          ++I;
          }           
        }
        else
          Serial.println("** ERROR: File is empty...");
      }
      Serial.println();
      file.closeFile();
    }
    else
    {
      switch(res)
      {
        case ERROR_ANOTHER_FILE_OPEN:
          Serial.println("** ERROR: Another file is already open...");
          break;
        default:
          Serial.print("** ERROR: ");
          Serial.println(res, HEX);
          break;
      }
    }
  }
  else
    Serial.println("** ERROR: 'TEXTFILE.TXT' does not exist...");
   
  Serial.println();
  Serial.println();
  Serial.println("***** All done... *****");
 


void loop()
{
}

En dit is het textbestand dat ik wil inlezen. Het aantal regels in het bestand kan varieren, en de lengte van de regels ook.
Het bestand is als volgt opgebouwd: naam, temperatuur, tijd, temperatuur, tijd,...etc.
Standaard is de naam op de eerste positie, en daarna 1 of meerdere combo's van temperatuur en tijd.

Code:
eenstaps,66,60
tweestaps,50,10,60,20,68,5
driestaps,45,15,50,10,60,20,68,5

De output van de sketch is nu
Code:
eenstaps,66,60
Name:  :  eenstaps
Name:  :  66
Name:  :  60
tweestaps,50,10,60,20,68,5
Name:  :  tweestaps
Name:  :  50
Name:  :  10
Name:  :  60
Name:  :  20
Name:  :  68
Name:  :  5
driestaps,45,15,50,10,60,20,68,5
Name:  :  driestaps
Name:  :  45
Name:  :  15
Name:  :  50
Name:  :  10
Name:  :  60
Name:  :  20
Name:  :  68
Name:  :  5




***** All done... *****

Ik zou graag de waardes herkenbaar opgeslagen hebben. Bijvoorbeeld als 'maischXY'. Waarbij maisch de variabele is (geen idee wat voor type), X het regelnummer aangeeft en Y de positie.
Geen idee of iemand me nog begrijpt, of kan helpen. Maar niet geschoten is altijd mis.

Alvast bedankt.

Edwin.
Logged

The Netherlands
Offline Offline
Edison Member
*
Karma: 50
Posts: 1649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hoi Edwin.

Je hebt gelijk, ik heb geen idee wat je wil.
In eerste instantie dacht ik dat je een waarde wil kunnen verwerken, maar dat je verkeerde resultaten krijgt.
Als dat zo is, dan komt dat omdat je tekens inleest en geen waardes.
Je moet dan dus eerst die hele reeks binnenhalen (alles wat er tussen de twee komma's staat), en vervolgens een variabele van maken.
Maar het laatste stukje wijst er op dat je iets ander wil, alleen raak ik je daar kwijt.
Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi MAS3,

Ik was er al bang voor dat het niet goed over zou komen.
Wat ik wilde bereiken is dat het txt bestand wordt ingelezen, en ik dan per regel de waarden in variabelen zou krijgen.
Als voorbeeld, na het inlezen wil ik graag dat ik de volgende variabelen heb gevuld:
Regel1Var1=eenstaps
Regel1Var2=66
Regel1Var3=60
Regel2Var1=tweestaps
Enzovoorts.
Zoals gezegd, het bestand varieert kwa lengte, en de regel lengte is ook variabel.

Hopelijk verduidelijkt dit wat.
Logged

Forum Moderator
Belgium
Offline Offline
Edison Member
*****
Karma: 68
Posts: 1918
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

eschraven
Waar je volgens mij eens goed moet over nadenken is: hoe ga ik die waarden die ik inlees opslaan in het geheugen.
Wat jij volgens mij nodig hebt om te doen wat je hier omschrijft is een linked list.
Maar in arduino wereld (weinig geheugen en slecht geheugen management) lijkt me dat geen goed idee.
Wat wil je eigenlijk doen met de "gelezen nformatie"? Is het nodig om die steeds in het geheugen te hebben? Is het niet makkelijker om de informatie te lezen als je ze nodig hebt?

Met vriendelijke groet
Jantje
Logged

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 -

The Netherlands
Offline Offline
Edison Member
*
Karma: 50
Posts: 1649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, je wil dus toch waardes binnenhalen.
In het eerste deel van je bericht heb je het ook over herbruikbare variabelen.
Zoals Jantje al vertelde, moet je ook weten wat je er dan mee gaat doen.
Het geheugen is schaars en daar moet je dus slim mee om gaan.
Je kunt namelijk ook redeneren dat de data altijd beschikbaar is, want die SD kaart zit er nog steeds in (toch ?).

Maar goed.
Ik heb een jaartje geleden eens een hele routine bedacht om te doen wat jij nu wil bereiken.
Dat was leerzaam en ook leuk (omdat me dat gelukt is..), het ging daarbij om hexadecimale waarden in een string, met komma's gescheiden en die via een seriële verbinding binnen kwam.
Maar om te doen wat jij wil, moet je meer weten over de opbouw van jouw data.
Als je precies weet hoe die data is opgebouwd, kun je daar dus mee werken.
De komma's zijn al een hele hulp.
Die helpen je onderscheid te maken tussen de verschillende waardes.
De naam van de regel is het volgende hulpmiddel.
Als er een nieuwe regel begint, dan heeft die een e, t of d als eerste karakter.
Daarmee weet je dan dus om welke regel het gaat, en dan weet je dus ook hoeveel waardes er gaan komen.
Ik neem aan dat elke regel telkens hetzelfde aantal waardes heeft.
Nu moet je nog weten wat voor waardes je gaat binnen krijgen.
In jouw voorbeeld blijven ze allemaal binnen de 8 bits, en das erg mooi vanwege de beperkingen van het beschikbare geheugen.

Het nadeel van jouw aanpak tot nog toe lijkt mij te zijn dat je een voorbeeld hebt genomen en die niet helemaal begrijpt.
Daarvan kun je wel leren maar als je niet naar dit voorbeeld hebt toegewerkt door ander sketches te bekijken en aan te passen dan word het wel lastig.
Dus hebt je dat al eens gedaan, andere sketches bekeken en aangepast ?

Volgens mij is er een commando om een string om te zetten naar een variabele, maar ik kan 'm zo snel ook niet vinden.
Met een string bedoel ik dus een rijtje ASCII tekens.

Ik heb nu geen tijd meer, andere zaken te doen.
Maar  je moet nog wat zaken bekijken (of als je dat al gedaan hebt hier noemen).
Zoals hoe groot de waardes zijn (kleiner dan 256, of 65535 of niet, kunnen er ook negatieve waardes voorkomen ?).
Hoeveel waardes wil je opslaan, heb je die ook allemaal nodig ?
Word elke regel met een CR (Carriage Return) en/of LF (Line Feed) beëindigd ?
(CR/LF is wat er gebeurt als je in een tekstverwerker op enter drukt).

Als je precies weet hoe de regels zijn opgebouwd, kun je dat gebruiken.
Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hoi,

De waarden in het txt bestand zijn per regel relevant. Per regel is het de input voor een maisschema. Het schema heeft een naam, en vervolgens steeds paartjes van 2 getallen. Het eerste getal is een temperatuur, en komt dus nooit boven 100, het tweede getal is een tijdsduur in minuten. Deze kan dus wel boven de 100 komen, maar blijft onder de 256.
Wat ik nu wil bereiken is dat ik op basis van de naam een regel kan selecteren, en vervolgens met de temperaturen en tijden die daar achter staan verder in mijn programma kan werken.  Ze worden gebruikt om te checken of de respectievelijke temperaturen en tijden gehaald zijn of overschreden worden.

Hopelijk voegt dit wat toe?

Bedankt voor het meedenken.
Logged

The Netherlands
Offline Offline
Edison Member
*
Karma: 50
Posts: 1649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Jazeker voegt dat wat toe.
Het betekent dat je altijd tussen 0 en 255 blijft, en dus ook nooit een negatieve waarde zult hebben.
Daarmee kun  je dus elke waarde opslaan als een byte, en dat beperkt de opslagruimte die er voor nodig is aanzienlijk.
Je hebt voor de temperaturen dan zelfs nog wat bits over die je in een later stadium nog zou kunnen gebruiken, maar das wel een beetje tricky en zou ik niet doen als het niet per se nodig is.

Het is inmiddels al weer tijd om te gaan werken, dus heb ik geen tijd om hier nu verder op in te gaan.
Maar ik zal later nog ff kijken of ik dat stukje code wat ik in elkaar gebakken had kan laten zien.
Dan moet het eerst aangepast worden voor dit doel, want ik had er natuurlijk een heel andere toepassing voor.

Overigens zul je wellicht deze thread (kilk !) ook wel interessant vinden, met 194 postings wel ff doorbijten.
Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

The Netherlands
Offline Offline
Edison Member
*
Karma: 50
Posts: 1649
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nou, ik ben er achter welk commando het ook al weer was dat een string kan omzetten naar een waarde (ik zei eerder variabele, maar das natuurlijk niet waar).

Het gaat hierbij om StringToInt (klik !).
Die maakt dus een integer uit een cijferreeks.
Een integer is 2 bytes, en dus tussen 0 en 65535.
Via de link vind je ook een voorbeeld, maar ik kan me voorstellen dat die lastig te begrijpen is.
Maar kijk daar in ieder geval eens naar.
« Last Edit: August 26, 2014, 03:50:46 pm by MAS3 » Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Pages: [1]   Go Up
Jump to: