Hallo; Ik wil een temperatuur meten van 40graden plus, ik heb daarvoor een schets met een 100k NTC.Ik krijg een error kan iemand mij uitleggen water fout gaat ?
[Bericht gewijzigd door Bertjebuk op dinsdag 8 oktober 2024 13:58:33 (77%)
Hallo; Ik wil een temperatuur meten van 40graden plus, ik heb daarvoor een schets met een 100k NTC.Ik krijg een error kan iemand mij uitleggen water fout gaat ?
[Bericht gewijzigd door Bertjebuk op dinsdag 8 oktober 2024 13:58:33 (77%)
Dit is deschets.
// Definieer de pinnen
const int ntcPin = A0; // NTC aan analoge pin A0
const int ledPin = 0; // LED aan digitale pin 0
// Constante voor NTC
const int resistance = 100000; // 100k NTC
void setup() {
pinMode(ledPin, OUTPUT); // Stel de LED pin in als uitgang
}
void loop() {
// Lees de analoge waarde van de NTC
int ntcValue = analogRead(ntcPin);
// Bereken de temperatuur in graden Celsius
float voltage = ntcValue * (5.0 / 1023.0); // Aangenomen dat de voeding 5V is
float resistanceNTC = (5.0 - voltage) * resistance / voltage; // Bereken weerstand NTC
// Gebruik de Steinhart-Hart vergelijking of aangenomen curve voor NTC
// Voor eenvoud, gebruik een schatting:
float temperatureC = (1 / ((log(resistanceNTC / resistance) / 3950) + (1 / 298.15))) - 273.15;
// Controleer op temperatuur boven 40 graden
if (temperatureC > 40) {
digitalWrite(ledPin, HIGH); // Zet de LED aan
} else {
digitalWrite(ledPin, LOW); // Zet de LED uit
}
delay(1000); // Wacht 1 seconden voordat we opnieuw meten
}
en wat is de foutmelding...
Foutmelding :
invalid conversion from 'int' to 'analog_pin_t' [-fpermissive]
Dus A0 moet van het type analog_pin_t zijn.
Dat moet je dan in je sketch aanpassen:
const int ntcPin = A0;
moet dan veranderd worden naar
analog_pin_t ntcPin = A0;
en misschien kan die ook const:
const analog_pin_t ntcPin = A0;
bedankt voor het meedenken , maar dan krijg ik de volgende melding.Arduino:1.8.13 (Windows 10), Board:"ATtiny13, 9.6 MHz internal osc., EEPROM retained, BOD 2.7V, No bootloader"
text section exceeds available space in board
De schets gebruikt 1520 bytes (148%) programma-opslagruimte. Maximum is 1024 bytes.
Globale variabelen gebruiken 0 bytes (0%) van het dynamisch geheugen. Resteren 64 bytes voor lokale variabelen. Maximum is 64 bytes.
Schets is te groot; ga naar http://www.arduino.cc/en/Guide/Troubleshooting#size voor tips over het verkleinen van de schets.
Fout bij het compileren voor board ATtiny13
Dit rapport zou meer informatie bevatten met
"Uitgebreide uitvoer weergeven tijden compilatie"
optie aan in Bestand -> Voorkeuren.
Golden Member
is er uberhaubt wel een arduino op basis van een tiny13?
Anders kun je de hexfile mogelijk wel los flashen buiten arduino om, met atmel studio ofzo
Tja, float en logaritmes op een 1K processortje is ook wel erg ambitieus moet ik zeggen. Dan vind ik 1540 bytes nog best wel knap van de compiler.
En ook een bootloader in een 1K processor is een uitdaging, want dat snoept ook al een stuk geheugen op.
Dus je zult naar een grotere processor moeten, of een andere temp-sensor kiezen. Een LM35 of MCP9700 geeft meer kansen want die is lineair, maar dan nog zul je een programmer moeten gebruiken voor die Tiny13.
Het programma is te groot voor de ATtiny13, misschien door de log functie. De berekening vereenvoudigen is vast mogelijk. Je kan op je PC vast wel een lookup tabel maken met de verwachte ADC waardes waarbij je een actie wil laten doen. Want dat hoeft de arme ATtiny helemaal niet te doen natuurlijk.
EDIT: Een LED aanzetten boven de 40 graden zou met tientallen bytes aan machinecode moeten lukken. Exclusief bootloader.
[Bericht gewijzigd door Benadski op dinsdag 8 oktober 2024 15:13:05 (17%)
Golden Member
pak inderdaad een lookup table voor je NTC, al kost dat ook de nodige ruimte, maar zo nauwkeurig hoeft het allemaal niet te zijn lijkt me.
Met wat linearisaties kom je ook wel uit de voeten.
Ik zou zowieso niet voor het aller kleinste microcontrollertje gaan vandaag de dag.
De vraag is of je BETA van jouw NTC überhaubt matched met de 3950
[Bericht gewijzigd door Stijnos op dinsdag 8 oktober 2024 15:50:25 (11%)
Golden Member
Op dinsdag 8 oktober 2024 15:01:39 schreef Stijnos:
is er uberhaubt wel een arduino op basis van een tiny13?
Anders kun je de hexfile mogelijk wel los flashen buiten arduino om, met atmel studio ofzo
https://www.electronics-lab.com/project/how-to-program-attiny13attiny1…
Een lookup table voor de NTC is de simpele oplossing, maar als het echt alleen om die 40 graden gaat, kun je zelf één keer bepalen wat de ADC waarde is bij 40 graden, en daarmee vergelijken.
Ik probeer floating points altijd te vermijden, zeker als de processor daar geen hardware ondersteuning voor heeft.
Ik heb voor de opnemer de LM35 op genomen kom nu uit op 914 bytes met nieuwe code.
#include <avr/io.h>
#include <util/delay.h>
#define LM35_PIN 1 // Pin A1 voor de LM35
#define LED_PIN 0 // Pin PB0 voor de rode LED
void setup() {
ADMUX = (1 << REFS0) | LM35_PIN; // Referentie op AVcc, A1 selecteren
ADCSRA = (1 << ADEN) | (1 << ADPS2); // ADC aan, prescaler 16
DDRB |= (1 << LED_PIN); // LED_PIN als output
}
uint16_t readADC(uint8_t channel) {
ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // Kies kanaal
ADCSRA |= (1 << ADSC); // Start conversie
while (ADCSRA & (1 << ADSC)); // Wacht tot conversie klaar is
return ADC; // Retourneer de ADC waarde
}
void loop() {
uint16_t adcValue = readADC(LM35_PIN);
// Bereken de temperatuur in Celsius (spanning/RIJ1 = 0.01V per graad)
float temperature = (adcValue / 1024.0) * 5000.0; // In millivolts
temperature /= 100.0; // Omrekenen naar Celsius
if (temperature >= 40.0) {
PORTB |= (1 << LED_PIN); // Zet LED aan
} else {
PORTB &= ~(1 << LED_PIN); // Zet LED uit
}
_delay_ms(1000); // Wacht 1 seconde
}
int main() {
setup();
while (1) {
loop();
}
}
#define T40 819 //Berekende waarde voor 40 graden Celsius (4V)
...
if (readADC(LM35_PIN) >= T40) {
...
Zo kan het ook, zeker met slechts 1 waarde scheelt dit enorm.
Nu merk je ook dat je berekening of je commentaar verkeerd is. Bij 4V komt er 40 graden uit je berekening, maar dat komt niet overeen met 0,01V/graad
Als je het nu zonder float probeert, zal het nog veel kleiner worden. Zodra je één berekening met een float doet, moet de floating point library meegenomen worden.
float temperature = (adcValue / 1024.0) * 5000.0; // In millivolts
temperature /= 100.0; // Omrekenen naar Celsius
if (temperature >= 40.0) {
Wordt met alleen integers
Unsigned long temperature = (adcValue * 5000) / 1024; // In millivolts, dus stappen van 0.1 graden C
if (temperature >= 400) {
Let op dat je eerst moet vermenigvuldigen, en dan pas delen, anders gooi je heel veel bitjes weg (in dit geval komt er dan altijd 0 uit). Daarbij moet je weer opletten voor overflows, maar 1024 * 5000 past gemakkelijk in een 32-bit integer, dus dat gaat hier altijd goed.
Golden Member
ik zou ook een kleine hysterese inbouwen.
Als de temp rond de 40 graden komt gaat je led als een debiel knipperen waarschijnlijk.
dus iets van >40 aan < 39.5 uit
Let op dat je eerst moet vermenigvuldigen, en dan pas delen, anders gooi je heel veel bitjes weg (in dit geval komt er dan altijd 0 uit). Daarbij moet je weer opletten voor overflows, maar 1024 * 5000 past gemakkelijk in een 32-bit integer, dus dat gaat hier altijd goed.
En met floats heb je geen last van dit geneuzel.
En het heeft ook geen nut om het kleiner -en moeilijker leesbaar- te maken als het al in de processor past. Dus lekker zo laten.
Zodra je één berekening met een float doet, moet de floating point library meegenomen worden.
Dat was wel zo misschien, maar dat is lang geleden. De compiler pakt alleen wat hij nodig heeft. De rest van de library komt niet mee.
[Bericht gewijzigd door deKees op woensdag 9 oktober 2024 18:07:48 (21%)
@BertjeBuk:
Je zet REFS0 op 1. Daarmee kies je de interne reference voor de A/D converter en dus niet Vcc. Dat is wel beter, want dan heb je geen last van voedings-spannings variaties, en de A/D ingang wordt gevoeliger.
Maar dan klopt het commentaar niet op verschillende plekken.
En dan moet je ook de formule aanpassen. Die is nu voor een 5V referentie.
- Reference is 1.1V nominaal (1100mV), dat komt overeen met 1024 counts uit de A/D
- De LM35 geeft 10mV per graad.
- Dus
float temperature = adcValue * (1100. / 1024) / 10.0;
Op woensdag 9 oktober 2024 17:45:15 schreef deKees:
En met floats heb je geen last van dit geneuzel.
En het heeft ook geen nut om het kleiner -en moeilijker leesbaar- te maken als het al in de processor past. Dus lekker zo laten.
Het past echt net, de TS zegt 914 bytes gebruikt, van de 1024 bytes flash die een Attiny13 heeft. Dat maakt dus erg weinig ruimte voor dingen die er nog bij komen.
Dat was wel zo misschien, maar dat is lang geleden. De compiler pakt alleen wat hij nodig heeft. De rest van de library komt niet mee.
Ik bedoelde vooral dat het weinig uitmaakt of je één of 10 floats gebruikt, het is niet zo dat het bij elke float extra veel groter wordt, totdat je een functie gaat gebruiken die je eerder niet had gebruikt.
Daar komt nog bij dat dergelijke berekeningen zonder hardware versnelling erg veel CPU tijd kosten vergeleken met integer berekeningen. Met deze ene berekening zal de TS dat niet merken, maar bij complexere berekeningen op hoge frequenties (zeg, 1kHz of nog sneller) gaat dat echt wel effect hebben.
Natuurlijk zijn floats wel lekker gemakkelijk, maar een goede programmeur kan het ook zonder als het nodig is.
[Bericht gewijzigd door SparkyGSX op woensdag 9 oktober 2024 18:34:39 (21%)
Je kunt ook de compiler het zware werk laten doen:
uint16_t TempLimit = 40. * ((1024. / 1100) * 10.0);
if (adcValue >= TempLimit)
{
Dan past het weer in 114 bytes.
En als je wilt weten wat die getallen betekenen:
float CountPerMillivolt = 1024./1100.;
float MillivoltPerDegree = 10.;
uint16_t TempLimit = 40. * MillivoltPerDegree * CountPerMillivolt;
if (adcValue >= TempLimit)
{
Dat blijft dan 114 bytes.
Ja dat kan, als je echt alleen die grens wilt weten, en die grens nooit verandert. Als je van die grens een instelling wilt maken, die je eventueel in EEPROM opslaat of zo, gaat dat natuurlijk niet meer.
Wel grappig dat je op die manier floats in je code hebt, maar omdat de compiler het resultaat daarvan al kan berekenen, krijg je geen floating point berekeningen in de code voor de microcontroller.
Met al deze gegevens ga ik een nieuwe schets maken en uitproberen het resultaat word gepost.
Golden Member
voor dat lm35 voorbeeld wat je poste, kun je net zo goed avr studio pakken.
dat gebruikt helemaal niks meer van arduino
Op donderdag 10 oktober 2024 12:38:42 schreef Bertjebuk:
Met al deze gegevens ga ik een nieuwe schets maken en uitproberen het resultaat word gepost.
Zolang je "schets" blijft roepen lijkt het er op dat eea in een "arduino' geflashed moet worden. Voor een 'tiny13' moet je dan een programmer hebben. Heb je die?
Je kunt een andere Arduino gebruiken als programmer.