Ik mis opeens mijn komma (punt)
16 berichten
• Pagina 1 van 2 • 1, 2
Ik mis opeens mijn komma (punt)
In mijn sketch van het zonnepaneel ,mis ik opeens een komma (punt) van mijn stroom meting op de LCD-display, dus nog 1 cijfer achter de komma.
Waarschijnlijk kijk ik er al weer te lang naar en/of er overheen, maar ik ben dus weer eens gestrand
Wie kan me zeggen waar ik de mist in ga ?
Serialmonitor geeft wel goed weer.
20:41:00.121 -> Amps 0.68
Deze waarde wordt opgehaald met currentValue uit de sketch.
Op LCD in dit blok.
// PRINT LOAD CURRENT LCD ROW 3
Waarschijnlijk kijk ik er al weer te lang naar en/of er overheen, maar ik ben dus weer eens gestrand
Wie kan me zeggen waar ik de mist in ga ?
Serialmonitor geeft wel goed weer.
20:41:00.121 -> Amps 0.68
Deze waarde wordt opgehaald met currentValue uit de sketch.
Op LCD in dit blok.
// PRINT LOAD CURRENT LCD ROW 3
- Code: Alles selecteren
/* SOLARTRACKER
*
* IN AND OUTPUTS Arduino (nano)
* A0 = tr - input LDR top right
* A1 = br - input LDR bototm right
* A2 = tl - input LDR top left
* A3 = bl - input LDR bottom left
* A4 = input sda LCD 4x20
* A5 = input scl LCD 4x20
* A6 = input potentiometer 10k for tolerange between all LDR's
* A7 = input current module ACS712
*
* D9 = in1 - outnput L298N - motor left/right
* D10 = in2 - output L298N - motor left/right
* D11 = in3 - output L298N -motor up/down
* D12 = in4 - output L298N - motor up/down
*
* SHORTCUTS IN SKETCH
* avt = average value top LDR's tl and tr
* avb = average value bottom LDR's bl and br
* avl = average value left LDR's tl and bl
* avr = average value right LDR's tr and br
* dvv = differenge value vertical avt and avb
* dvh = difference value horizontal avl and avr
* aav = average azimute value
* aev = average elevation value
* aavn = average azimuth value night
* aevn = average elevation value night
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//-------------------------------------------------------
// SET I2C ADDRESS FOR LCD
//-------------------------------------------------------
LiquidCrystal_I2C lcd(0x27,20,4); // LCD address workbench
// LiquidCrystal_I2C lcd(0x3F,20,4); // LCD address solarpanel
//-------------------------------------------------------
// MOTOR AZIMUTH
//-------------------------------------------------------
int in1 = 9; // D9 output to in1 L298N module
int in2 = 10; // D10 output to in2 L298N module
//-------------------------------------------------------
// MOTOR ELEVATION
//-------------------------------------------------------
int in3 = 11; // D11 output to in3 L298N module
int in4 = 12; // D12 output to in4 L298N module
//-------------------------------------------------------
// START LOOP ACTIVE RUNTIME
//-------------------------------------------------------
unsigned long currentMillis; // Current time
unsigned long previousMillis; // Past time
unsigned long interval = 180000; // Startup runtime motors for position 3*1000mS*60S=3min
int enableState = HIGH; // Start with ON
//-------------------------------------------------------
//START PRINTTIME
//-------------------------------------------------------
unsigned long previousMillisPrint; // Serial print
const unsigned long intervalPrint = 10000UL; // Serial print interval 10 seconds
//-------------------------------------------------------
// CURRENT SENSOR ACS712
//-------------------------------------------------------
const int currentPin = A7;
int sensitivity = 100; // 185=5A 100=20A 66=30A
int adcValue= 0;
int offsetVoltage = 2500; // For DC output is + and -
double adcVoltage = 0;
double currentValue = 0;
void setup()
{
Serial.begin(115200); // Initialize the serial port
lcd.begin(); // Initialize LCD
lcd.backlight(); // ON
//-------------------------------------------------------
// PIN ASSIGN
//-------------------------------------------------------
pinMode(in1, OUTPUT); // D9 to module in1 L298N
pinMode(in2, OUTPUT); // D10 to module in2 L298N
pinMode(in3, OUTPUT); // D11 to module in3 L298N
pinMode(in4, OUTPUT); // D12 to todule in3 L298N
pinMode(A0, INPUT); // Top left LDR
pinMode(A1, INPUT); // Top right LDR
pinMode(A2, INPUT); // Bottom left LDR
pinMode(A3, INPUT); // Bottom right LDR
pinMode(A6, INPUT); // Potentiometer reading tolerance LDR's
pinMode(A7, INPUT); // Sensor ACS712 currentmeter battery
//-------------------------------------------------------
// PRINT START MESSAGE TO SERIALMONITOR
//-------------------------------------------------------
Serial.println(F("MONITOR STARTED"));
Serial.println(F("NEW VALUES WILLBE ACTIVE IF"));
Serial.println(F("SOLARPANEL GOTO START POSITION"));
}
void loop()
{
//-------------------------------------------------------
// ROUTINE FLAG TO RUN ASYNCHONE TIMER
//-------------------------------------------------------
currentMillis = millis(); // Set loop time ON
if (currentMillis - previousMillis >= interval)
{
// HAS TIME PASSED ?
previousMillis = currentMillis; // Remember last value
if (enableState == HIGH)
{
// IS STATE ON ?
interval = 1800000; // Set next loop time 30min (1*1000*60*30)
enableState = LOW; // Set state OFF
}
else
{
// IS STATE OFF ?
interval = 180000; // Set motor run time 3min (1*1000*60*3)
enableState = HIGH; // Set state on
}
}
//-------------------------------------------------------
// LDR LIGHT SENSORS
//-------------------------------------------------------
int tr = analogRead(A0); // LDR top right
int br = analogRead(A1); // LDR bottom right
int tl = analogRead(A2); // LDR top left
int bl = analogRead(A3); // LDR bottom left
// SET TOLERANCE SENSORS VALUES 0 - 50
int tolerance = analogRead(A6)/40.96; // Difference 50 between sensors
// AVERAGE VALUE LDR'S
int avt = (tr + tl) / 2; // Average value top
int avb = (bl + br) / 2; // Average value down
int avl = (tl + bl) / 2; // Average value left
int avr = (tr + br) / 2; // Average value right
// AVERAGE DIFFERENCE OF TOP AND BOTTOM LIGHT SENSORS
int dvv = avt - avb;
// AVERACE DIFFERENCE OF LEFT AND RIGHT LIGHT SENSORS
int dvh = avl - avr;
// AVERAGE VALUE AZIMUTE NIGHT
int aav = (avt + avb) / 2;
int aavn = 300; // set Average Azimuth Value Night here
// AVERAGE VALUE ELEVATION NIGHT
int aev = (avl + avr) / 2;
int aevn = 300; // set Average Elevator Value Night here
//-------------------------------------------------------
// RECALCULATE VALUE CURRENT SENSOR
//-------------------------------------------------------
adcValue = analogRead(A7);
adcVoltage = (adcValue / 1024.0) * 5000;
currentValue = ((adcVoltage - offsetVoltage) / sensitivity);
//-------------------------------------------------------
// PRINT DEBUG INFORMATION EVERY intervalPrint time
//-------------------------------------------------------
{
unsigned long currentMillis = millis();
if( currentMillis - previousMillisPrint >= intervalPrint)
{
previousMillisPrint = currentMillis;
// DEBUG INFORMATION
Serial.println();
Serial.print(F("*******NEW*******"));
Serial.println();
Serial.print(F("Active loop\t"));
Serial.println(interval/1000);
Serial.print(F("Loop time\t"));
Serial.println((interval/1000) - (currentMillis-previousMillis)/1000);
Serial.println();
Serial.print(F("Amps\t\t"));
Serial.println(currentValue);
Serial.print(F("mVoltage A7\t"));
Serial.println(adcValue);
Serial.print(F("mVolt calc\t"));
Serial.println(adcVoltage);
Serial.println();
Serial.print(F("Tolerance\t"));
Serial.print(tolerance);
Serial.println();
Serial.println();
Serial.print(F("+UP<>DOWN-\t"));
Serial.print(dvv);
Serial.println();
Serial.print(F("AVT - up\t"));
Serial.print(avt);
Serial.println();
Serial.print(F("AVB - down\t"));
Serial.print(avb);
Serial.println();
Serial.println();
Serial.print(F("+WEST<>EAST-\t"));
Serial.print(dvh);
Serial.println();
Serial.print(F("AVL - west\t"));
Serial.print(avl);
Serial.println();
Serial.print(F("AVR - east\t"));
Serial.print(avr);
Serial.println();
Serial.println();
Serial.print(F("Top Left\t"));
Serial.print(tl);
Serial.println();
Serial.print(F("Top Right\t"));
Serial.print(tr);
Serial.println();
Serial.print(F("Bottom Left\t"));
Serial.print(bl);
Serial.println();
Serial.print(F("Bottom Right\t"));
Serial.print(br);
Serial.println();
Serial.println();
Serial.print(F("ELEVATION DOWN\t"));
Serial.println(avt < avb);
Serial.print(F("ELEVATION UP\t"));
Serial.println(avt > avb);
Serial.print(F("ELEVATION STOP\t"));
Serial.println(-1*tolerance < dvv || dvv < tolerance);
Serial.print(F("ELEVATION NIGHT\t"));
Serial.println(aev <= aevn);
Serial.println();
Serial.print(F("AZIMUTH WEST\t"));
Serial.println(avr < avl);
Serial.print(F("AZIMUTH EAST\t"));
Serial.println(avr > avl);
Serial.print(F("AZIMUTH STOP\t"));
Serial.println(-1*tolerance < dvh || dvh < tolerance);
Serial.print(F("AZIMUTH NIGHT\t"));
Serial.println(aav <= aavn);
Serial.print(F("*******END*******"));
Serial.println();
}
}
//-------------------------------------------------------
// CHECK DIFFERANGE BETWEEN SENSORS UP AND DOWN FOR ELEVATION
//-------------------------------------------------------
if ((-1*tolerance > dvv || dvv > tolerance) && (aev >= aevn)) // check difference in top/bottom LIGHT SENSORS is greater than tolerance
{
// CHANGE ELEVATION MOTOR DIRECTION
if (avt < avb) // If average LIGHT SENSOR values on top side are smaller than on bottom side then elevation motor rotates CLOCKWISE
{
// SET ELEVATION MOTOR DOWN
digitalWrite(in3, HIGH && enableState);
digitalWrite(in4, LOW);
lcd.setCursor(0,0);
lcd.print(F("ELEVATION : DOWN")); // print lcd row 1
}
else // If average LIGHT SENSOR values on bottom side are greater than on top side then elevation motor rotates COUNTERCLOCKWISE
{
// SET ELEVATION MOTOR UP
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH && enableState);
lcd.setCursor(0,0);
lcd.print(F("ELEVATION : UP"));// Print lcd row 1
}
}
else if (-1*tolerance < dvv || dvv < tolerance) // If difference is smaller than tolerance, STOP elevation motor
{
// STOP ELEVATION MOTOR
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
lcd.setCursor(0,0);
lcd.print(F("ELEVATION : STOP")); // Print lcd row 1
// MOVE ELEVATION MOTOR NIGHT POSITION
if (aev <= aevn) // Sensor values night
{
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
lcd.setCursor(0,0);
lcd.print(F("ELEVATION : NIGHT")); // Print lcd row 1
}
}
//-------------------------------------------------------
// CHECK DIFFERANGE BETWEEN SENSORS LEFT AND RIGHT FOR AZIMUTH
//-------------------------------------------------------
if ((-1*tolerance > dvh || dvh > tolerance) && (aav >= aavn)) // Check difference in left and right LIGHT SENSORS is within tolerance range
{
// CHANGE AZIMUTH MOTOR DIRECTION
if (avr < avl) // If average LIGHT SENSOR values on left side are greater than right side, azimuth motor rotates CLOCKWISE
{
// SET AZIMUTH MOTOR WEST = LEFT
digitalWrite(in1, HIGH && enableState);
digitalWrite(in2, LOW);
lcd.setCursor(0,1);
lcd.print(F("AZIMUTH : WEST")); // Print lcd row 2
}
else // If average LIGHT SENSOR values on right side are greater than on left side, azimuth motor rotates COUNTERCLOCKWISE
{
// SET AZIMUTH MOTOR EAST = RICHT
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH && enableState);
lcd.setCursor(0,1);
lcd.print(F("AZIMUTH : EAST")); // Print lcd row 2
}
}
else if (-1*tolerance < dvh || dvh < tolerance) // If difference is smaller than tolerance, STOP azimuth motor
{
// STOP AZIMUTH MOTOR
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
lcd.setCursor(0,1);
lcd.print(F("AZIMUTH : STOP")); // Print lcd row 2
}
// MOVE AXIMUTH MOTOR NIGHT POSITION / RIGHT
if (aav <= aavn) // Sensor values night
{
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
lcd.setCursor(0,1);
lcd.print(F("AZIMUTH : NIGHT")); // Print lcd row 2
}
{
//-------------------------------------------------------
// PRINT VALUES ON LCD - ROW 1 AND 2 FROM PROGRAM
//-------------------------------------------------------
// PRINT LOAD CURRENT LCD ROW 3
lcd.setCursor(0,2);
lcd.print(F("LOAD CURRENT:"));
char temp1[5]; // Enough spaces for 4 numbers
snprintf(temp1,6, "%5d", currentValue); // %5d = 5 digets, right aligned
lcd.print(temp1);
lcd.setCursor(19,2);
lcd.print("A");
// PRINT TOLERANCE LCD ROW 4
lcd.setCursor(0,3);
lcd.print(F("TOL:"));
char temp2[5]; // Enough spaces for 4 numbers
snprintf(temp2,4, "%3d", tolerance); // %3d = 3 digets, right aligned
lcd.print(temp2);
// PRINT LOOP TIME LCD ROW 4
lcd.setCursor(8,3);
lcd.print(F("LOOP:"));
char temp3[5]; // Enough spaces for 5 numbers
snprintf(temp3,6, "%5d", ((interval - (currentMillis-previousMillis))/1000)); // // %5d = 5 digets, right aligned
lcd.print(temp3);
lcd.setCursor(19,3);
lcd.print(F("S"));
delay(300);//
}
}
Advertisement
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: Ik mis opeens mijn komma (punt)
%5d is 5 cijfers ZONDER . Of ,. Daarnaast reserveer je 5 bytes terwijl je er 6 nodig hebt.
Re: Ik mis opeens mijn komma (punt)
Waarom heb ik er 6 nodig, het grootste getal wat daar kan komen te staan is 10.00 of -10.00 als je de min mee telt.
- Code: Alles selecteren
//-------------------------------------------------------
// PRINT VALUES ON LCD - ROW 1 AND 2 FROM PROGRAM
//-------------------------------------------------------
// PRINT LOAD CURRENT LCD ROW 3
lcd.setCursor(0,2);
lcd.print(F("LOAD CURRENT:"));
char temp1[5]; // Enough spaces for 4 numbers
snprintf(temp1,6, "%5d", currentValue); // %5d = 5 digets, right aligned
lcd.print(temp1);
lcd.setCursor(19,2);
lcd.print("A");
Re: Ik mis opeens mijn komma (punt)
Dat komt omdat je een spijkerbroek aan hebt die twee maten te klein is waardoor je niet helder kunt denken
Je kunt beter de char temp[5] een stuk of 20 groot maken, of 40, maar niet twee maten te klein
Ik gebruik meestal dezelfde variabele, die noem ik meestal "buffer", voor dit soort omzettingen.
Zodra je de tekst naar het scherm hebt verstuurd, dan kun je die "buffer" voor iets anders gebruiken.
Als er ergens iets mis gaat, dan wil je niet dat een fout door heel je sketch dendert en de hele Arduino crasht.
Stel dat de sensor los komt en je krijgt 1023 graden of zo iets voor de temperatuur.
Of je maakt een foutje in je sketch, waardoor de interval toch groter wordt.
%5d betekent minimaal 5 posities, het wordt aangevuld aan de linkerkant met spaties, en dan komt er nog een zero-terminator bij. Als je de ruimte voor een zero-terminator vergeet, dan gaat het al meteen mis. Als het getal door een foutje meer ruimte inneemt dan -10 ... +10, dan gaat het ook mis.
http://www.cplusplus.com/reference/cstdio/printf/
Dit zit me toch al niet lekker:
Je zet een 32-bit unsigned long op de stack, en daar haal je een integer van af. Bij een Arduino Uno is die integer 16-bit, en bij een ESP8266 is het 32-bit. Het hangt dus maar net van het boardje af, of dat het toevallig goed gaat. Het zijn allemaal "unsigned long" variabelen, dus als het resultaat negatief zou worden, dan komt er als getal misschien 2147483646 uit, dat zijn 10 tekens, plus een zero-terminator maakt 11.
Je kunt beter de char temp[5] een stuk of 20 groot maken, of 40, maar niet twee maten te klein
Ik gebruik meestal dezelfde variabele, die noem ik meestal "buffer", voor dit soort omzettingen.
Zodra je de tekst naar het scherm hebt verstuurd, dan kun je die "buffer" voor iets anders gebruiken.
Als er ergens iets mis gaat, dan wil je niet dat een fout door heel je sketch dendert en de hele Arduino crasht.
Stel dat de sensor los komt en je krijgt 1023 graden of zo iets voor de temperatuur.
Of je maakt een foutje in je sketch, waardoor de interval toch groter wordt.
%5d betekent minimaal 5 posities, het wordt aangevuld aan de linkerkant met spaties, en dan komt er nog een zero-terminator bij. Als je de ruimte voor een zero-terminator vergeet, dan gaat het al meteen mis. Als het getal door een foutje meer ruimte inneemt dan -10 ... +10, dan gaat het ook mis.
http://www.cplusplus.com/reference/cstdio/printf/
Dit zit me toch al niet lekker:
- Code: Alles selecteren
snprintf(temp3,6, "%5d", ((interval - (currentMillis-previousMillis))/1000));
Je zet een 32-bit unsigned long op de stack, en daar haal je een integer van af. Bij een Arduino Uno is die integer 16-bit, en bij een ESP8266 is het 32-bit. Het hangt dus maar net van het boardje af, of dat het toevallig goed gaat. Het zijn allemaal "unsigned long" variabelen, dus als het resultaat negatief zou worden, dan komt er als getal misschien 2147483646 uit, dat zijn 10 tekens, plus een zero-terminator maakt 11.
Re: Ik mis opeens mijn komma (punt)
Maar even beginnen wat ik snap (denk ik), de "d" zou een "u" moeten zijn ?
Wat ik nog niet snap is het stukje de currentValue.
Als ik bv char temp1[5] verander in char temp1[20] gaat het op de rest van de display helemaal fout.
Op regel 2 (AZIMUTH) veranderen de eerste letters (2 soms 4) in allerlei vreemde karakters.
Ik krijg ook nog steeds een heel getal 0 ipv een getal als 00.00 of -00.00
Tijdelijk heb ik de sketch aangepast op deze manier, maar ik heb het gevoel dat dat niet juist manier is.
- Code: Alles selecteren
snprintf(temp3,6, "%5u", ((interval - (currentMillis-previousMillis))/1000));
Wat ik nog niet snap is het stukje de currentValue.
- Code: Alles selecteren
/-------------------------------------------------------
// PRINT VALUES ON LCD - ROW 1 AND 2 FROM PROGRAM
//-------------------------------------------------------
// PRINT LOAD CURRENT LCD ROW 3
lcd.setCursor(0,2);
lcd.print(F("LOAD CURRENT:"));
char temp1[5]; // Enough spaces for 4 numbers
snprintf(temp1,6, "%5d", currentValue); // %5d = 5 digets, right aligned
lcd.print(temp1);
lcd.setCursor(19,2);
lcd.print("A");
Als ik bv char temp1[5] verander in char temp1[20] gaat het op de rest van de display helemaal fout.
Op regel 2 (AZIMUTH) veranderen de eerste letters (2 soms 4) in allerlei vreemde karakters.
Ik krijg ook nog steeds een heel getal 0 ipv een getal als 00.00 of -00.00
Tijdelijk heb ik de sketch aangepast op deze manier, maar ik heb het gevoel dat dat niet juist manier is.
- Code: Alles selecteren
//-------------------------------------------------------
// PRINT VALUES ON LCD - ROW 1 AND 2 FROM PROGRAM
//-------------------------------------------------------
// PRINT LOAD CURRENT LCD ROW 3
lcd.setCursor(0,2);
lcd.print(F("LOAD CURRENT:"));
char temp1[3]; // Enough spaces for 3 numbers
//-----Temp-----------
lcd.setCursor(14,2);
lcd.print(currentValue);
//----Temp------------
lcd.print(temp1);
lcd.setCursor(18,2);
lcd.print(F(" A"));
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: Ik mis opeens mijn komma (punt)
Waarom zou die %d een %u moeten zijn? Beide zijn nog steeds fout trouwens. Je hebt een breuk (decimalen). Dat is een float. Ik zou eens dtostrf() googelen als ook snprintf(). Die laatste om te begrijpen wat je aan het doen bent. Die eerste hoe je een float in een char array zet. Het aantal bytes van de buffer mag wel 20 zijn maar bedenk dat een char array altijd afgesloten wordt met een \0. Dus wil je 5 bytes vullen heb je 6 bytes nodig. Ga je die laatste byte overschrijven dan gaat een print() functie door tot hij een \0 tegen komt
Re: Ik mis opeens mijn komma (punt)
Vraag: hoe......
Antwoord: RTFM cq zoek op Google.
Was het vroeger bij mijn lerarenopleiding maar zo makkelijk, dan gaf ik vast ook HBO-niveau les
Antwoord: RTFM cq zoek op Google.
Was het vroeger bij mijn lerarenopleiding maar zo makkelijk, dan gaf ik vast ook HBO-niveau les
Re: Ik mis opeens mijn komma (punt)
Ik weet niet welk Arduino board en welke LiquidCrystal_I2C library je gebruikt. Het is goed mogelijk dat jouw LiquidCrystal_I2C library de Arduino "Print" class gebruikt en dus ook floating point getallen kan laten zien.
Dan hoef je alleen maar een extra spatie te zetten als het 0.00 of groter is, en dan met twee decimalen afdrukken.
Kun je dat eens proberen ? Dan blijf je uit de buurt van problemen.
Een Arduino Uno of Arduino Mega heeft geen 'double', alleen maar 'float'.
Bij een Arduino Uno of Arduino Mega kunnen de printf()-functies geen floating point getallen aan. Dat is er uitgehaald.
Wanneer je een floating point getal wilt omzetten naar tekst, dan is er de dtostrf().
https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html
Ook daar is de 'width' de minimum 'width.
De printf()-functies kijken niet naar het type van de extra parameters. Je moet dan zelf bijhouden welke dingen verwacht worden met %d, %u, %ld en zo, en dan heel secuur precies die dingen op de stack zetten. Zit er ergens een byte fout, dan gaat alles daarna fout. Het is dus geen eenvoudige functie om zomaar even te gebruiken.
Ik zie dat je twee variabelen hebt die allebei "currentMillis' heten. Eentje is globaal en eentje is lokaal binnen de loop(). Dat is verwarrend. Kun je dat corrigeren ? Daar komt geen foutmelding op, omdat de compiler vaste regels heeft om daar mee om te gaan (lokale variabele krijgt voorrang).
Dan hoef je alleen maar een extra spatie te zetten als het 0.00 of groter is, en dan met twee decimalen afdrukken.
Kun je dat eens proberen ? Dan blijf je uit de buurt van problemen.
- Code: Alles selecteren
float currentValue;
...
lcd.setCursor(0,2);
lcd.print(F("LOAD CURRENT:"));
if(currentValue >= 0.0)
{
lcd.print(F(" "));
}
lcd.print(currentValue,2);
lcd.setCursor(19,2);
lcd.print("A");
Een Arduino Uno of Arduino Mega heeft geen 'double', alleen maar 'float'.
Bij een Arduino Uno of Arduino Mega kunnen de printf()-functies geen floating point getallen aan. Dat is er uitgehaald.
Wanneer je een floating point getal wilt omzetten naar tekst, dan is er de dtostrf().
https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html
Ook daar is de 'width' de minimum 'width.
De printf()-functies kijken niet naar het type van de extra parameters. Je moet dan zelf bijhouden welke dingen verwacht worden met %d, %u, %ld en zo, en dan heel secuur precies die dingen op de stack zetten. Zit er ergens een byte fout, dan gaat alles daarna fout. Het is dus geen eenvoudige functie om zomaar even te gebruiken.
Ik zie dat je twee variabelen hebt die allebei "currentMillis' heten. Eentje is globaal en eentje is lokaal binnen de loop(). Dat is verwarrend. Kun je dat corrigeren ? Daar komt geen foutmelding op, omdat de compiler vaste regels heeft om daar mee om te gaan (lokale variabele krijgt voorrang).
Re: Ik mis opeens mijn komma (punt)
Ik gebruik een Nano en de LiquidCrystal_I2C library die jij me hebt aanbevolen.
Ik heb indertijd alle libs weg gedaan en ben "schoon" begonnen, er staan dus geen dubbele of libs die ik niet gebruik meer in.
Met dat % ben ik heel lang aan het stoeien geweest, maar daar kwam ik echt niet uit.
Deels werkt het en aan de andere kant voor geen meter, inderdaad gaat dan de hele display (sketch) op tilt.
Liever gebruik ik het (nog) niet in een sketch omdat ik de functie nog niet goed snap en er dus (te) veel fout kan gaan.
Met de door jou gemaakt code blijf ik vreemd vinden dat ik maar 4 digits blijf houden, incl de min (-)
Ook als ik dit verander van 2 naar 1, lcd.print(currentValue,1); het blijft dus -0.0 A of 0.00 A
Is op zich niet zo erg, maar de ontlaadstroom (welke voor mij belangrijker is en altijd lager is) lees ik liever preciezer uit met -00.00 (5 digits)
De ontlaadstroom kan / zal ook nooit hoger zijn dan -10.00 A, deze wordt begrenst door de laadregelaar van het zonnepaneel.
Hieronder de wijzigingen welke ik heb aangebracht aangeven met <<<<<<<<<<<<<<<<<<.
Ergens in mijn ander topic staat dat ik de currentMillis zo vaak kan aanroepen als ik wil.....dat is dus niet met gelijke naam begrijp ik (?)
Je bedoelt waarschijnlijk de currentMillis welke ik gebruik voor de debuginformatie.
Ik heb deze nu verandert in currentMillsDebug en toegevoegd.
De compiler loopt er goed doorheen, serialmonitor en sketch doen het goed, dus ga ik er van uit dat ik het goed heb gedaan.
Ik heb indertijd alle libs weg gedaan en ben "schoon" begonnen, er staan dus geen dubbele of libs die ik niet gebruik meer in.
Met dat % ben ik heel lang aan het stoeien geweest, maar daar kwam ik echt niet uit.
Deels werkt het en aan de andere kant voor geen meter, inderdaad gaat dan de hele display (sketch) op tilt.
Liever gebruik ik het (nog) niet in een sketch omdat ik de functie nog niet goed snap en er dus (te) veel fout kan gaan.
Met de door jou gemaakt code blijf ik vreemd vinden dat ik maar 4 digits blijf houden, incl de min (-)
Ook als ik dit verander van 2 naar 1, lcd.print(currentValue,1); het blijft dus -0.0 A of 0.00 A
Is op zich niet zo erg, maar de ontlaadstroom (welke voor mij belangrijker is en altijd lager is) lees ik liever preciezer uit met -00.00 (5 digits)
De ontlaadstroom kan / zal ook nooit hoger zijn dan -10.00 A, deze wordt begrenst door de laadregelaar van het zonnepaneel.
Hieronder de wijzigingen welke ik heb aangebracht aangeven met <<<<<<<<<<<<<<<<<<.
- Code: Alles selecteren
//-------------------------------------------------------
// RECALCULATE VALUE CURRENT SENSOR
//-------------------------------------------------------
adcValue = analogRead(A7);
adcVoltage = (adcValue / 1024.0) * 5000;
float currentValue; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
currentValue = ((adcVoltage - offsetVoltage) / sensitivity);
.
.
.
//-------------------------------------------------------
// PRINT VALUES ON LCD - ROW 1 AND 2 FROM PROGRAM
//-------------------------------------------------------
lcd.setCursor(0,2);
lcd.print(F("LOAD CURRENT:"));
if (currentValue >= 0.0);
{
lcd.print(F(" "));
}
lcd.print(currentValue,1); //<<<<<<<<<<<<<<<<<<<<<<<<<<<
lcd.setCursor(18,2);
lcd.print(F(" A"));
Ergens in mijn ander topic staat dat ik de currentMillis zo vaak kan aanroepen als ik wil.....dat is dus niet met gelijke naam begrijp ik (?)
Je bedoelt waarschijnlijk de currentMillis welke ik gebruik voor de debuginformatie.
Ik heb deze nu verandert in currentMillsDebug en toegevoegd.
- Code: Alles selecteren
//-------------------------------------------------------
// START LOOP ACTIVE RUNTIME
//-------------------------------------------------------
unsigned long currentMillisDebug; // Debug time <<<<<<<<<<<<<<<<<<<<<<<<<
unsigned long currentMillis; // Current time
unsigned long previousMillis; // Past time
unsigned long interval = 180000; // Startup runtime motors for position 3*1000mS*60S=3min
int enableState = HIGH; // Start with ON
De compiler loopt er goed doorheen, serialmonitor en sketch doen het goed, dus ga ik er van uit dat ik het goed heb gedaan.
- Code: Alles selecteren
//-------------------------------------------------------
// PRINT DEBUG INFORMATION EVERY intervalPrint time
//-------------------------------------------------------
{
unsigned long currentMillisDebug = millis(); //<<<<<<<<<<<<<<<<<<<<<<<<
if( currentMillisDebug - previousMillisPrint >= intervalPrint)
{
previousMillisPrint = currentMillisDebug;
// DEBUG INFORMATION
Re: Ik mis opeens mijn komma (punt)
Uhm, ja, ik had daar niet goed over nagedacht. De Arduino "Print" class gaat afronden. De extra nul die je ziet is waarschijnlijk blijven staan van een vorige keer.
Je kunt noemen dat een Nano gebruikt en een link geven naar de LiquidCrystal_I2C library. Je kan ook een link geven naar je vorige onderwerp waar dat stond. Ik kan niet onthouden wat iedereen gebruikt
Je kunt één 'currentMillis' maken, en die overal in de loop() gebruiken.
Maak een keuze of je die variabele globaal of lokaal wilt.
Bij lokaal (alleen geldig binnen de loop() ), wordt het dit:
En dan kun je die 'currentMillis' overal in de loop() gebruiken.
De Arduino "Print" class zijn alle functies met Serial.println() en lcd.print(), enzovoorts.
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Print.cpp.
De Arduino "Print" class kán gebruiken worden. Ik heb gezien dat sommigen een soort van tweetrapsraket gebruiken. De "Print" functies geven namelijk terug hoeveel tekens geschreven worden.
Dan zou je een 'dummy' aanroep kunnen doen, en daarna zelf berekenen hoeveel spaties nodig zijn, vervolgens die spaties schrijven, gevolgd door een echte aanroep met lcd.print().
Voor een precies formaat zijn de printf(), snprintf(), etc. functies heel handig. Maar dan moet je wel weten wat je doet.
De floating point support heeft Arduino er uit helaas uit gesloopt, zoals ik schreef. Dat hebben ze gedaan omdat het veel ruimte in beslag nam voor een ATmega8
Voor een floating point is er dan nog dtostrf(), die Nico al noemde.
Ik kan je gerust stellen, dit is zo'n beetje alles wat er is om een floating point af te drukken.
Er is de Arduino "Print" class, de dtostrf() en dtostre(), en voor alles-behalve-float zijn er de printf() functies.
Je kunt noemen dat een Nano gebruikt en een link geven naar de LiquidCrystal_I2C library. Je kan ook een link geven naar je vorige onderwerp waar dat stond. Ik kan niet onthouden wat iedereen gebruikt
Je kunt één 'currentMillis' maken, en die overal in de loop() gebruiken.
Maak een keuze of je die variabele globaal of lokaal wilt.
Bij lokaal (alleen geldig binnen de loop() ), wordt het dit:
- Code: Alles selecteren
void loop()
{
unsigned long currentMillis = millis();
...
}
En dan kun je die 'currentMillis' overal in de loop() gebruiken.
De Arduino "Print" class zijn alle functies met Serial.println() en lcd.print(), enzovoorts.
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Print.cpp.
De Arduino "Print" class kán gebruiken worden. Ik heb gezien dat sommigen een soort van tweetrapsraket gebruiken. De "Print" functies geven namelijk terug hoeveel tekens geschreven worden.
Dan zou je een 'dummy' aanroep kunnen doen, en daarna zelf berekenen hoeveel spaties nodig zijn, vervolgens die spaties schrijven, gevolgd door een echte aanroep met lcd.print().
Voor een precies formaat zijn de printf(), snprintf(), etc. functies heel handig. Maar dan moet je wel weten wat je doet.
De floating point support heeft Arduino er uit helaas uit gesloopt, zoals ik schreef. Dat hebben ze gedaan omdat het veel ruimte in beslag nam voor een ATmega8
Voor een floating point is er dan nog dtostrf(), die Nico al noemde.
- Code: Alles selecteren
// 5 is 5 tekens, inclusief punt en min teken, geschoven naar rechts
// -5 is geschoven naar links.
// 2 is twee cijfers achter de komma
// buffer is een buffer die groot genoeg is.
char buffer[20];
dtostrf( currentValue, 5, 2, buffer);
lcd.print( buffer);
Ik kan je gerust stellen, dit is zo'n beetje alles wat er is om een floating point af te drukken.
Er is de Arduino "Print" class, de dtostrf() en dtostre(), en voor alles-behalve-float zijn er de printf() functies.
16 berichten
• Pagina 1 van 2 • 1, 2
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 44 gasten