Vreemd resultaat

Arduino specifieke Software
Gebruikers-avatar
Berichten: 43
Geregistreerd: 09 Jan 2015, 15:09

Vreemd resultaat

Berichtdoor hv0805 » 30 Sep 2016, 09:32

Ik ben bezig met het uitlezen van water, gas en elec tellers. Het is de bedoeling om dit in eerste instantie naar een SD card te schrijven en nadien ook naar een MySQL database op een Rasberry te sturen. Alles werkt tot nu toe alleen is het resultaat dat weggeschreven wordt op de SD card nogal vreemd.
Hieronder de code die ik nu gebruik om de data weg te schrijven. Hierin bevindt zich nog de Serial.Print die ik als debug gebruik en die, als alles werkt terug verwijderd wordt. Ook om te testen lijkt de laatste lijn nogal vreemd vandaag=now.minute(), maar ook dit is weer als test, zodat ik geen ganse dag op het resultaat moet wachten, nadien wordt dit vandaag=now.day().
Op dit ogenblik test ik enkel met LwPuls en GasPuls, vandaar dat de anderen op NUL blijven.
Wat is het probleem nu?

In het bestand krijg ik dit als resultaat

Do-29 20:20 | 14 ,0 ,25 ,0
Do-29 20:25 | 12 ,0 ,22 ,0
Do-29 20:27 | 0 ,0 ,0 ,0
Do-29 20:28 | 28 ,0 ,16 ,0
Vr-30 9: 8 | 4 ,0 ,11 ,0

M.a.w de plaatsen GasPuls en RwPuls zijn omgedraaid, het resultaat moet zijn Vr-30 9: 8 | 4 ,11 ,0 ,0 want in de code staan ze op deze plaats LwPuls,GasPuls,RwPuls,ElecPuls

Ik heb totaal geen idee hoe dit komt (Op zich is dit geen probleem, de resultaten zijn juist, ik moet enkel rekening houden dat ik ze anders interpreteer.)

Dank u

Herman


cpp code
void DagSD()
{
Serial.print("LwPuls:");
Serial.println(LwPuls);
Serial.print("GasPuls:");
Serial.println(GasPuls);
Serial.print("RwPuls:");
Serial.println(RwPuls);
Serial.print("ElecPuls:");
Serial.println(ElecPuls);
now=RTC.now();
char tmpmaand[14];
sprintf(tmpmaand,"%4d_%s.txt",now.year(),maanden[now.month()]);
dataFile = SD.open(tmpmaand, FILE_WRITE);
char titel[50];
sprintf(titel,"%s-%d %2d:%2d | %d ,%d ,%d ,%d ",weekdagen[now.dayOfTheWeek()],now.day(),now.hour(),now.minute(),LwPuls,GasPuls,RwPuls,ElecPuls);
dataFile.println(titel);
dataFile.close();
delay(500); // 0.5 sec wachten
dataFile.close();

LwPuls=0;
RwPuls=0;
GasPuls=0;
ElecPuls=0;
vandaag=now.minute();
}

Advertisement

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Vreemd resultaat

Berichtdoor nicoverduin » 30 Sep 2016, 10:31

Waarom neem je aan dat het hier fout gaat? Je neemt klakkeloos aan dat dat het hier fout gaat. Maar als je variabelen verkeerd gevuld worden dan gaat het verder ook fout. Wat je op de serial ziet is in de zelfde volgorde als naar de SD.
Ik vermoed dat je ergens in jouw code GasPuls en RwPuls verkeerd zit te vullen.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 43
Geregistreerd: 09 Jan 2015, 15:09

Re: Vreemd resultaat

Berichtdoor hv0805 » 30 Sep 2016, 14:59

Overal waar ik een Serial.print uitvoer van de variabelen worden ze op de juiste wijze afgeprint.
Dus eerst LwPuls, dan GasPuls, dan RwPuls en als laatste ElecPuls. In die volgorde schrijf ik ze ook weg naar het bestand:

sprintf(titel,"%s-%d %2d:%2d | %d ,%d ,%d ,%d ",weekdagen[now.dayOfTheWeek()],now.day(),now.hour(),now.minute(),LwPuls,GasPuls,RwPuls,ElecPuls);

maar in het bestand zelf staat de Gaspuls op locatie 3 en niet op locatie 2 zoals ik zou verwachten.
Ik doe de test met maar 2 inputsensors zodat de laatste (RwPlus en ElecPuls) altijd 0 zouden moeten zijn.(wat ze ook zijn bij een Serial.print)
Ik ben totaal geen idee wat er mis kan zijn.

Herman

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Vreemd resultaat

Berichtdoor nicoverduin » 30 Sep 2016, 15:11

Kan best allemaal maar geen sketch betekent geen energie in steken.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 43
Geregistreerd: 09 Jan 2015, 15:09

Re: Vreemd resultaat

Berichtdoor hv0805 » 30 Sep 2016, 15:27

Die snap ik niet.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Vreemd resultaat

Berichtdoor Koepel » 30 Sep 2016, 15:51

De wet van Koepel (geintje, maar toch) : "Vijftig procent kans dat het probleem zit in het deel dat je vanaf het begin negeerde, omdat je dacht dat het probleem niet veroorzaakt zou kunnen worden door dat deel".
http://forum.arduino.cc/index.php?topic=362380.msg2498377#msg2498377

Het zou kunnen zijn, dat de stack iets raars doet, omdat je ram geheugen vol is. Maar waarschijnlijk kijk je steeds over iets heen. Dat gebeurt ons allemaal en daar is dit forum ook voor ;)

Je kunt dit doen aan het begin van de funktie:
Code: Alles selecteren
 LwPuls = 10;
 GasPuls = 20;
 RwPuls = 30;
 ElecPuls = 40;

En dan kijken wat er op de seriele monitor verschijnt en wat er naar het bestand wordt geschreven.

Geven de now.day() functies een integer terug van 2 bytes ? (volgens mij wel, dus %d is okay).

Je kunt dezelfde opbouw gebruiken om tekst naar de seriele monitor te sturen. Dus je kunt de hele opbouw met print() en println() ook voor de SD kaart gebruiken, en je kunt de sprintf() gebruiken voor de seriele monitor. Dat is de eenvoudigste test, om de "titel" ook naar de seriele monitor te sturen.

Zou je de "dataFile" niet tweemaal willen sluiten ? Als dat nodig is, dan heb je een serieuze bug or geheugen problem. Je kunt niet de ene fout oplossen met de andere fout (tweemaal het bestand sluiten). Een delay() voor of na het sluiten is niet nodig.

Gebruikers-avatar
Berichten: 43
Geregistreerd: 09 Jan 2015, 15:09

Re: Vreemd resultaat

Berichtdoor hv0805 » 30 Sep 2016, 19:41

Koepel,

Dat had ik ook al gedaan, (waarden van RwPuls en ElecPuls op 99 gezet).
In feite is dit een routine die ik van een vorige config gekopieerd heb. Ik mijn vorige woning had ik dit al opgebouwd bij wijze van test. Nu zijn we verhuis naar een nieuwbouw en wil ik dit definitief gaan gebruiken. Er zijn t.o.v. de vorige test de waarden GasPuls en ElecPuls bijgekomen.
Dus vroeger werd geprint: ("....%d, %d ",Lwpuls, RwPuls) nu komt er dus ("....%d, %d, %d, %d ",Lwpuls, GasPuls, RwPuls, ElecPuls).
De reden waarom nu LwPuls en dan GasPuls staat is dat ik nu alleen nog maar het leidingwater en gas kan uitlezen. En logischer wijze zetten we dit dus achter elkaar.
Op zich maakt het niet veel uit waar wat staat, ik vindt het alleen vreemd en vind er geen verklaring voor.

Ik heb de 2e close weggehaald. Deze stond er nog van de vorige config en had toen ergens gelezen dat het beter was om de datafile 2 maal te sluiten met een kleine delay tussenin.
Wat kan het probleem zijn met het geheugen als ik dit doe?
Ik heb dit allemaal op een Mega uitgevoerd, dus denk ik dat er genoeg geheugen voorhanden is.
(Een Mega, want in de toekomst komt er nog NTP bij en een doorsturing naar MySQL op RAspberry en dat wordt krap voor een Uno)

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Vreemd resultaat

Berichtdoor Koepel » 01 Okt 2016, 19:10

Beste hv0805,
Zou je het volgende eens rustig willen doorlezen ?

Als iemand op een forum een klein stukje code geeft, dan zit het probleem vaak in de rest die we niet mogen zien.
Daar is een website voor : http://snippets-r-us.com/ (graag globaal lezen).

Iemand die serieus is, vraagt je om de hele sketch te laten zien.
Iemand die minder serieus is, zou kunnen zeggen dat het erg vermoeiend is om in een kristallen bol te kijken wat de rest van de code is, om daar vervolgens de fout in te kunnen ontdekken. Dat is nog best lastig, vooral als de kristallen bol een namaak-artikel is, zoals hier : http://forum.arduino.cc/index.php?topic=381531.0 (dat hoef je niet te lezen, maar ik vind het grappig, diegene gaat zelfs op mij pissen terwijl ik iets probeer duidelijk te maken).

Dus als we graag de hele sketch zien, dan verwachten we van je dat je de hele sketch laat zien.
Ik gaf een paar eenvoudige dingen om te testen, en dan verwacht ik van je dat je die ook echt gaat proberen. Dan verwacht ik ook dat je de tekst van de seriële monitor en van het bestand ook echt laat zien.

Wij willen namelijk niet horen of iets goed of fout gaat, wij willen zelf kunnen bepalen wat er gebeurt. Jij kijkt ergens overheen, dus de beste manier waarop wij kunnen helpen is door alles na te lopen. Dat kan alleen als we genoeg gegevens hebben.

Waarschijnlijk worden die variabelen ergens omgewisseld, misschien in de sketch, misschien in de hardware, misschien anders. Dus met de hele sketch, met schema's en foto's kunnen wij aangeven waar dat gebeurt.

Gebruikers-avatar
Berichten: 43
Geregistreerd: 09 Jan 2015, 15:09

Re: Vreemd resultaat

Berichtdoor hv0805 » 02 Okt 2016, 17:05

Hieronder de code en de resultaten, zoals je ziet wordt op seriele console de waarden voor de pulsen, LwPuls, GasPuls, LwPuls en Elecpuls in de juiste volgorde weergegeven, ook na het wegschrijven is dit zo.
De string naar de SD en op de SD card zelf worden de waarden van ElecPuls(40) en RwPuls(50) niet meer weergegeven en is de locatie van GasPuls opgeschoven.

cpp code
/*
Telleterstanden uitlezen
Int 0 1 / 2 3 \ 4 5
Pin 2 3 /21 22 \ 19 18
LW Gas /SDA SCL\ Elec RW

Int 2 en 3 kunnen niet gebuikt worden bij I2C modules

//********************************************************
Waterpuls LJ12A3-4-Z/BX Bruin=+ Blauw=- Zwart=Data
Spanning: tussen 6v en 36v
//********************************************************




*/
#include <stdio.h>
#include <Wire.h>
#include <SPI.h> // communicating with Serial Peripheral Interface (SPI) Bus
#include <SD.h> // for SD card
/*********************************************************************
* File for SD to save data
**********************************************************************/
int bestandOK=0; // controle om bestand aan te maken
String dateTime;
File dataFile;
/*******************************************************************************
* change this to match your SD shield or module;
* Arduino Ethernet shield: pin 4
*******************************************************************************/
const uint8_t chipSelect = 4;

//**********************************
//*** Clock config en variablen ***
#include <DS3231.h>
#include <RTClib.h>
DS3231 Clock;
RTC_DS3231 RTC;
DateTime now;
bool Century=false;
bool h12;
bool PM;

volatile int jaar,dag,maand,weekdag,uur,minuut,seconde;
volatile int vandaag, huidigeMaand; // var om dagtellers en maandtellers te laten zien

const char* maanden[] = {" ","Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec"};
const char* weekdagen[] = {"Zo","Ma","Di","Wo","Do","Vr","Za"};


// set pin numbers:
const byte LwaterPin = 2; // int 0 LeidingWater
const byte GasPin = 3; // int 1 Gas
const byte ElecPin = 19; // int 19 Electriciteit
const byte RwPin = 18; // int 18 Regenwater


//**************** Dagtellers **************
volatile unsigned long LwPuls=0; // 0 to 4,294,967,295
volatile unsigned long GasPuls=0;
volatile unsigned long ElecPuls=40; // 40 en 50 tijdens test, nadien terug 0
volatile unsigned long RwPuls=50;
//**************** Maandtellers ************
volatile unsigned long LwMaandPuls=0; // 0 to 4,294,967,295
volatile unsigned long GasMaandPuls=0;
volatile unsigned long ElecMaandPuls=0; // 40 en 50 tijdens test, nadien terug 0
volatile unsigned long RwMaandPuls=0;

boolean LwUpPuls=false; // word TRUE bij puls en in loop() terug op FALSE gezet
boolean GasUpPuls=false; // wordt gebruikt om led puls aan te sturen
boolean ElecUpPuls=false;
boolean RwUpPuls=false;

//*******************Debounce parameters***********************//
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void setup() {
// initialize the LED pin as an output:
Serial.begin(9600);

pinMode(52, OUTPUT); // SS pin 52 on Mega

// initialize the sensors pin as an input:
pinMode(LwaterPin, INPUT_PULLUP);
pinMode(GasPin, INPUT_PULLUP);
pinMode(ElecPin, INPUT_PULLUP);
pinMode(RwPin, INPUT_PULLUP);


attachInterrupt(digitalPinToInterrupt(LwaterPin), LwaterRoutine, RISING);
attachInterrupt(digitalPinToInterrupt(GasPin), GasRoutine, RISING);
attachInterrupt(digitalPinToInterrupt(ElecPin), ElecRoutine, RISING);
attachInterrupt(digitalPinToInterrupt(RwPin), RwRoutine, RISING);

Wire.begin();



if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
else
{
Serial.println("initialization done.");

}

now=RTC.now();
vandaag=now.minute(); // schrijft huidige dag in var // minute() tijdens testfase, nadien terug day()
huidigeMaand=now.month(); // schrijft huidige maand in var


}

void loop() {
now=RTC.now();
Serial.print(LwPuls);
Serial.print(" ");
Serial.print(GasPuls);
Serial.print(" ");
Serial.print(ElecPuls);
Serial.print(" ");
Serial.print(RwPuls);
Serial.println();
Serial.println(now.minute());

//*********** Dagtellers wegschijven ******************
if (now.minute()!= vandaag) // minute() tijdens testfase, nadien terug day()
{
DagSD();
}

//*********** Maandtellers resetten ******************
if (now.month()!= huidigeMaand)
{
LwMaandPuls=0;
RwMaandPuls=0;
GasMaandPuls=0;
ElecMaandPuls=0;
huidigeMaand=now.month();
}
}

// *************** dagtellers wegschrijven naar SD en tellers resetten ******************
void DagSD()
{
now=RTC.now();
char tmpmaand[14];
sprintf(tmpmaand,"%4d_%s.txt",now.year(),maanden[now.month()]);
dataFile = SD.open(tmpmaand, FILE_WRITE);
char titel[50];
Serial.println(titel);
Serial.print(LwPuls);
Serial.print("- ");
Serial.print(GasPuls);
Serial.print("- ");
Serial.print(ElecPuls);
Serial.print("- ");
Serial.print(RwPuls);
Serial.println();
sprintf(titel,"%s-%d %2d:%2d | %d, %d ,%d ,%d ",weekdagen[now.dayOfTheWeek()],now.day(),now.hour(),now.minute(),LwPuls,GasPuls,RwPuls,ElecPuls);
dataFile.println(titel);
dataFile.close();

Serial.println(titel);
Serial.print(LwPuls);
Serial.print(" ");
Serial.print(GasPuls);
Serial.print(" ");
Serial.print(ElecPuls);
Serial.print(" ");
Serial.print(RwPuls);
Serial.println();
LwPuls=0;
RwPuls=0;
GasPuls=0;
ElecPuls=0;
vandaag=now.minute();
}

//************************** interrupt routine Leiding water **************************
void LwaterRoutine()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis(); // If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200) {
LwPuls++;
LwMaandPuls++;
LwUpPuls=true; // nodig om led te laten oplichten
}
last_interrupt_time = interrupt_time;
}

//************************** interrupt routine GAS **************************
void GasRoutine()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis(); // If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200) {
GasPuls++;
GasMaandPuls++;
GasUpPuls=true; // nodig om led te laten oplichten
}
last_interrupt_time = interrupt_time;
}

//************************** interrupt routine Electriciteit **************************
void ElecRoutine()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis(); // If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200) {
ElecPuls++;
ElecMaandPuls++;
ElecUpPuls=true; // nodig om led te laten oplichten
}
last_interrupt_time = interrupt_time;
}

//************************** interrupt routine Regenwater **************************
void RwRoutine()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis(); // If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200) {
RwPuls++;
RwMaandPuls++;
RwUpPuls=true; // nodig om led te laten oplichten
}
last_interrupt_time = interrupt_time;
}
Bijlagen
2016_OKT.jpg
Inhoud bestand op SD
2016_OKT.jpg (33.73 KiB) 10525 keer bekeken
SerialConsole.jpg
Fig van de Console
SerialConsole.jpg (25.97 KiB) 10525 keer bekeken

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Vreemd resultaat

Berichtdoor Koepel » 02 Okt 2016, 17:29

Bedankt voor de hele sketch :D
Als je verteld welke RTC en welke DS3231 library je gebruikt (links er naar toe bijvoorbeeld), dan kan ik het compileren.

Dus alle interrupts met de variabelen voor de pulsen en de bounce onderdrukking werkt dus ?

Er vallen me een paar dingen op.
Je gebruikt de volgorde : LwPuls, GasPuls, ElecPuls, RwPuls.
Met de sprintf gebruik je een andere volgorde : LwPuls, GasPuls, RwPuls, ElecPuls

Een normale funktie heeft maar één type voor een parameter. De compiler geeft al snel een foutmelding als het verkeerde type wordt gebruikt.

De Serial.print() functie accepteert verschillende soorten variabelen en past zich aan. Als je een 'int' gebruikt, dan is het een andere Serial.print() dan wanneer je een 'unsigned long' gebruikt. Er zijn dus een aantal verschillende funkties voor de Serial.print().

Maar nu de sprintf(), die heeft geen normale parameter, maar een variabele lijst. Als je een unsigned long gebruikt, dan gaat er 4 bytes op de stack. En de sprintf() heeft geen idee wat er allemaal op de stack staat. Als je vervolgens "%d" gebruikt, dan haalt sprintf() maar twee byte van de stack, en de volgende "%d" haalt de volgende twee byte van de stack.

Je zet unsigned long (variabelen van 4 byte) op de stack en met "%d" gebruik je maar 2 byte. Die nullen zijn de twee andere bytes.

Tjsa, dat is helaas een nadeel van de sprintf(). Je kunt "%ld" gebruiken voor 4 byte decimaal, of de parameter forceren naar een integer met: (int) LwPuls, (int) GasPuls, (int) RwPuls, (int) ElecPuls

De tekst in het bestand kun je nog wat mooier maken.
Je kunt bijvoorbeeld nullen voor een getal zetten, het getal naar links aan laten sluiten, en nog meer. Als de code werkt, dan kun je eens wat proberen met "%02d" of "%-d" en dat soort dingen.
http://www.cplusplus.com/reference/cstdio/printf/

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 20 gasten