Go Down

Topic: kommagetallen op CSV bestand (Read 2019 times) previous topic - next topic

kevinvanhee

Dag iedereen

Voor een project op school log ik data op een SD-kaartje. Dit doe ik met de VMA-202 van Velleman en de DHT11 sensor. Deze waarden wil ik dan in Excel verwerken.
Het probleem is dat de waarden op mijn SD-kaart geschreven worden met puntjes en niet met komma's. Hierdoor leest Excel deze niet uit als getallen. Is er een mogelijk om de waardes met komma's uit te lezen van deze sensor?
Hieronder mijn programma.
Voorbeeld hoe data op CSV komt.

0; 59.00; 21.00
10; 59.00; 21.00
20; 82.00; 14.00
30; 82.00; 15.00
40; 80.00; 15.00
50; 78.00; 16.00
60; 75.00; 17.00
70; 69.00; 18.00
80; 68.00; 18.00
90; 69.00; 17.00

Alvast bedankt!
Kevinvanhee


sterretje

#1
Jun 02, 2019, 12:33 pm Last Edit: Jun 02, 2019, 12:35 pm by sterretje
Je kunt de getallen met bv 100 vermenigvuldigen en daarna omzetten naar een int. Vervolgens delen door 100 om het gedeelte voor de komma te krijgen en modulo 100 gebruiken om het gedeelte na de komma te krijgen. Vervolgens de individuele nummers wegschrijven naar SD, gescheiden door een komma.

PS Kleine programmas ( minder dan 9000 karakters ) kun je in je post plaatsen met code tags zoals hier onder

[code]je programma hier[/code]

Code: [Select]
// SD kaart datalogger.
// Openen van bibliotheken waar sensor op werkt.
#include <dht.h>
//#include <SPI.h>
#include <SD.h>
// Definiëren van costanten.

double Tijd;
const double dhtPin =  2;
const double sdPin = 10;
dht DHT;

void setup() {
  SD.begin(sdPin);
  delay(500);
  }
  // Openen van de SD-kaart.
void loop() {
  // Openen van bestand. Naam kan aangepast worden naar eigen believen.
  File dataFile = SD.open ("datalog.txt", FILE_WRITE);
 
  if (dataFile){
    DHT.read11(dhtPin);
   
    Tijd = millis()/1000.00;
// eerst gewoon 1000 nu met puntje: 2 cijfers na komma.
// Tijd in minuten.
// Wegschrijven van de data op de SD-kaart.
    dataFile.print (Tijd);
    dataFile.print ("; ");
    dataFile.print(DHT.humidity);
    dataFile.print("; ");
    dataFile.println(DHT.temperature);
    dataFile.close();
    delay (1000); //aantal seconden tussen metingen (x1000)
  }
}
p/code]
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

MAS3

Hoi kevinvanhee, welkom.

Je vraag komt volgens mij niet helemaal overeen met de output die je laat zien.
In die output staan geen puntjes, maar puntkomma's, ik neem daarom aan dat dat jouw probleem is ?

Verder is het niet zo handig om een bestand toe te voegen die iemand moet downloaden, terwijl het prima mogelijk is om dit op het forum te tonen (alleen als je een code hebt die uit veel regels bestaat lukt dat niet).
Dit is jouw code nadat die eerst wat netter geformatteerd is en klaar gemaakt om op het forum te plaatsen (met de tools die je daarvoor hebt in de IDE):

Code: [Select]

// SD kaart datalogger.
// Openen van bibliotheken waar sensor op werkt.
#include <dht.h>
//#include <SPI.h>
#include <SD.h>
// Definiëren van costanten.

double Tijd;
const double dhtPin =  2;
const double sdPin = 10;
dht DHT;

void setup() {
  SD.begin(sdPin);
  delay(500);
}
// Openen van de SD-kaart.
void loop() {
  // Openen van bestand. Naam kan aangepast worden naar eigen believen.
  File dataFile = SD.open ("datalog.txt", FILE_WRITE);

  if (dataFile) {
    DHT.read11(dhtPin);

    Tijd = millis() / 1000.00;
    // eerst gewoon 1000 nu met puntje: 2 cijfers na komma.
    // Tijd in minuten.
    // Wegschrijven van de data op de SD-kaart.
    dataFile.print (Tijd);
    dataFile.print ("; ");
    dataFile.print(DHT.humidity);
    dataFile.print("; ");
    dataFile.println(DHT.temperature);
    dataFile.close();
    delay (1000); //aantal seconden tussen metingen (x1000)
  }
}


Als ik die code naast jouw probleem leg, dan zie ik dat je in regels 30 en 32 zelf de puntkomma's neerzet.
Dus is het enige dat je moet doen, zorgen dat je daar het gewenste teken invoert.

Als dit niet het probleem is, en je de puntjes in de waarden voor temperatuur en vochtigheid bedoelt, dan komt dat doordat dit een Amerikaanse wijze van getalnotatie betreft.
Die gebruik je ook in de programmeertalen zoals C++ in geval van Arduino.
Nederlanders gebruiken een punt bij bijvoorbeeld 10.000, Amerikanen gebruiken dan een komma dus dan word het 10,000.
Alleen krijg je wel een probleem met je CSV bestand als je dit op een of andere wijze zou aanpassen, omdat daar een komma van groot belang is (Comma Separated Values).
Ook in programmeertalen hebben komma's een belangrijke functie.
Daarom kun je je Excel ook laten werken met de Amerikaanse getalnotatie.
Het nadeel daarvan is dan weer dat je dat bij iedere computer zo moet instellen waar je van je data gebruik wil maken.
Ik heb geen idee of Excel de mogelijkheid biedt de getalnotatie in een bestand te converteren.
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

kevinvanhee

Dankuwel MAS3 en sterretje voor de snelle respons.

Het probleem zit hem inderdaad in de Amerikaanse notatie van de getallen.
Die eerste methode vind ik vrij omslachtig omdat het aan mensen net iets makkelijker uit te leggen is als ze het puntje moeten vervangen door een komma in Excel zelf.

Bedankt voor de hulp!

shooter

dat kan in excel gewoon bij import, daar kun je aangeven hoe een getal inelkaar zit.
simpeler is om de nationaliteit te veranderen naar engels.
paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

septillion

#5
Jun 05, 2019, 03:10 pm Last Edit: Jun 05, 2019, 03:11 pm by septillion
Inderdaad meerdere opties met voor en nadelen:

- Tijdens de import kan je bij geavanceerd aangeven wat het decimaal teken (maar ook voor duizendtallen) is. Voordeel, flexibel. Nadeel, omslachtig als je het vaak moet doen.

- Locatie in Windows aanpassen naar een land met een punt als decimaalteken. Voordeel: snel als je veel in één keer moet doen. Nadeel, telkens in Windows klooien

- Of je past je programma aan dat deze het juiste decimaalteken gebruikt. Eventueel schakelbaar als je zowel gebruikers met punt als met komma hebt. Of zelfs naar twee bestanden. Voordeel: snel en flexibel. Nadeel: meer code en ligt dan vast in bestand (maar kan met bovengenoemde dingen altijd weer opgelost worden. En twee bestanden nemen natuurlijk ook dubbel zo veel ruimte in.

- Bestand eerst openen in Notepad(++) en een find and replace all doen. Voordeel, universeel. nadeel, extra stap.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

nicoverduin

Dit kwam ik tegen op stack exchange en zeker de moeite waard:
Code: [Select]
/**
 * programma      : CommaForDot
 * Doel           : Afdrukken van een komma voor de decimale punt
 * Gekopieerd van : https://arduino.stackexchange.com/questions/46817/how-to-use-a-coma-as-the-decimal-separator
 * Interessante manier om in plaats van een decimale punt een komma af te drukken of naar
 * een SD kaart teschrijven
 */
#include <Arduino.h>
#include <SPI.h>
#include <SD.h>

// door deze regel toe te voegen wordt een punt vervangen door een komma
#define DECIMALE_KOMMA

/**
 * @class CommaForDot
 * Deze class gewoon boven in jouw programma kopieren
 */
class CommaForDot: public Print {
public:
  CommaForDot(Print &downstream) :
      downstream(downstream) {
  }
  virtual size_t write(uint8_t c) {
    // hier wordt us een decimale punt vervangen door een komma
    return downstream.write(c == '.' ? ',' : c);
  }
private:
  Print &downstream;
};



// globale variabelen
const int chipSelect = 10;

/**
 * @name setup
 * Initialiseren van het programma
 */
void setup() {
  // Opzetten IO
  Serial.begin(9600);

  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1)
      ;
  }
  Serial.println("card initialized.");
}

/**
 * @name loop
 * Wordt eindeloos aangeroepen vanuit main()
 */
void loop() {

  float mvStap = 5.0 / 1024;        // aantal millivolt per stap
  static int8_t teller = 50;        // schrijf 50 records weg

  // schrijf aantal records weg
  if (teller > 0) {

    // file elke keer openen en sluiten zodat alle data zaker is opgeslagen
    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // if the file is available, write to it:
    if (dataFile) {

      // creer een instantie van de CommaForDot en koppel deze aan de FILE stream
      CommaForDot filteredSerial(dataFile);

      // schrijf gefilterde data weg als CSV.
      // wat er nu gebeurt is dat data die naar filteredSerial wordt gestuurd
      // de punt wordt vervangen door een komma.
      // Dus filteredSerial en dataFile zijn dezelfde bestemmingen

#ifdef DECIMALE_KOMMA
      filteredSerial.print((analogRead(A0) * mvStap));
#else
      dataFile.print((analogRead(A0) * mvStap));
#endif
      dataFile.print(";");

#ifdef DECIMALE_KOMMA
      filteredSerial.print((analogRead(A1) * mvStap));
#else
      dataFile.println((analogRead(A1) * mvStap));
#endif

      dataFile.close();
    }
    // if the file isn't open, pop up an error:
    else {
      Serial.println("error opening datalog.txt");
    }
    teller--;
  } else {
    Serial.println("Klaar....");
  }
}


Zie verder: https://arduino.stackexchange.com/questions/46817/how-to-use-a-coma-as-the-decimal-separator

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