Gå til innhold

Den lille Arduino-tråden


Anbefalte innlegg

Så vidt jeg forstår baserer det der seg på at termistoren er lineær, noe den absolutt ikke er.

 

Termistorer pleier å ha oppgitt A, B og C/D koeffisienter i databladet. Om du ikke finner disse, kan du bruke Steinhart-hart metoden for å beregne det. Les deg litt opp på dette, står blant annet litt på wiki. Du må da gjøre tre målinger innenfor spekteret du ønsker (f.eks. 0 grader, 20 grader og 50 grader) og avlese resistansen i termistoren i disse 3 scenarioene og kjøre hele leksa inn i en "3 likninger med 3 ukjente".

 

Ta kontakt om du møter på problemer ;)

 

Edit: brukte denne kilden litt for beregningen: http://www.arduino.cc/playground/ComponentLib/Thermistor2

Endret av r2d290 waits for alice
Lenke til kommentar
Videoannonse
Annonse

Er dette NTC din: http://www.produal.com/folders/Files/Tekniset%20esitteet%20EN/TEATNTC20ea.pdf

I så fall bør det vell fungere greit å bruke den tabellen som står der til å beregne temperaturen, og gjøre lineær approksimering i mellom punktene om du ikke trenger 100% nøyaktighet (den ser ikke ut til å være veldig lineær, men du vil i alle fall ikke bomme med mer en et par grader).

 

Du måler spenningen i spenningsdeleren, bruk dette og den kjente motstanden til å beregne motstanden i NTC sensoren, slå opp i tabellen og beregn deg fram til ca verdi for temperatur.

 

Hvis du trenger mer hjelp med denne metoden så kan jeg sikkert komme med et eksempel i kveld når jeg har litt bedre tid.

Lenke til kommentar
Er dette NTC din: http://www.produal.c...TEATNTC20ea.pdf

I så fall bør det vell fungere greit å bruke den tabellen som står der til å beregne temperaturen, og gjøre lineær approksimering i mellom punktene om du ikke trenger 100% nøyaktighet (den ser ikke ut til å være veldig lineær, men du vil i alle fall ikke bomme med mer en et par grader).

 

det er vel strengt tatt det jeg har gjort, men da vil jeg bare få målinger fra ca 10 til 40 grader, noe som er for lite målbart område...

hvis jeg får det til, kan det hende at jeg trapper hele sensoren i kjøleblokka på bilen, og der må jeg vite om det er 41 grader eller 91 grader, noe som ikke går med dagens oppsett om du skjønner =)

Lenke til kommentar

Har et lite prosjekt på gang her hvor jeg tenkte å overstyre en fjernkontroll for å fjernstyre en strømbryter. Ser ut til at Clas Ohlson har slutta å selge denne typen så får ikke linka til den typen.

 

Under her ser dere et bilde av kretskortet til fjernkontrollen, har lodda av 4 av bryterne jeg tenkte å styre. Batteriet er på 12v og spenningen på bryterne er 5v. Hvordan overstyrer jeg disse bryterne? Har skjønt jeg må bruke transistorer, men kan ikke så mye om de forskjellige typene. Har også lurt på hva som vil skje om jeg kjører 5v rett på brytern fra arduinoen? Er redd for å ødelegge noe :p

 

post-22814-0-84635400-1321002645_thumb.jpg

 

 

Vet jeg kunne programmert en egen sender, men nå hadde jeg dette liggende så får bare bruke det jeg har liggende.

 

Planen var å lage en termostat med mulighet for overstyring via internett, har et ethernet-shield liggende her jeg tenkte å ta i bruk.

Lenke til kommentar

 

..snip

 

 

Takk for svar :) ble opptatt med litt andre ting en stund, derfor fikk jeg aldri svart tidligere.

 

Jeg løste problemet med en while-løkke. Dermed holder programmet stand så lenge knappen var trykket inn. Gikk nemlig ikke helt opp for meg med en gang at problemet var nettopp at den gjorde som jeg ba den om.. sikkert bare 400 ganger innen jeg trykket ferdig :blush:

Lenke til kommentar

det er vel strengt tatt det jeg har gjort, men da vil jeg bare få målinger fra ca 10 til 40 grader, noe som er for lite målbart område...

hvis jeg får det til, kan det hende at jeg trapper hele sensoren i kjøleblokka på bilen, og der må jeg vite om det er 41 grader eller 91 grader, noe som ikke går med dagens oppsett om du skjønner =)

 

Så vidt jeg kan se så vil koden du har skrevet gi deg 10 grader hvis ADCen (sensorValue) returnerer 0, og 40 grader om ADCen returnerer 1023, noe som er helt feil. sensorValue vil heller aldri være mindre enn 10 eller høyere enn 40 etter map funksjonen (om jeg har tippet dens funksjonalitet rett), så if-else her er litt bortkastet.

 

Her er noe jeg mener er mer korrekt:

 

static const uint16_t adctmp[] PROGMEM= 
{1012, 1006, 999, 988, 977,
 960, 939, 913, 880, 842, 
 797, 747, 691, 633, 572, 
 512, 453, 398, 346, 299,
 257, 221, 189, 161, 137,
 117, 100, 87, 73, 64, 
 54, 48, 42, 36, 30};

int getTemp(){
uint16_t* ptr = &adctmp;; //pointer to lookup table in flash
uint16_t adcval = analogRead(sensorPin); // read analog value
uint16_t idx = 0;
uint16_t tmp0, tmp1;
uint16_t temp, temp0, temp1;
//search through table looking for closest fit
tmp0 = pgm_read_byte(*ptr++);
while(adcval < tmp0){
	tmp1 = tmp0;
	tmp0 = pgm_read_byte(*ptr++);
	idx++;
}
//calculate the two temperatures (5 degrees per index in the table)
temp1 = ((idx-1)*5)-50; //lower limit 
//temp0 = ((idx)*5)-50;   //higher limit
//interpolate between these two
temp = temp1 + ((5*(tmp1-adcval))/(tmp1-tmp0));
//return final value
return temp;
}

 

 

Her har jeg først tatt tallene fra databladet og lagt inn i et spreadsheet (XL) dokument og lagt til de 5 graders intervallene som manglet (lineært interpolert). Så regnet jeg ut hva spenningen vil være ved de forskjellige temperaturene, og fant etter det den tilhørende ADC koden. Jeg kan da se at du skal kunne ha ca 0.5 grader oppløsning om jeg ikke har gjort noe feil. Tok så tallene for ADC kode og la inn i tabellen her, og så bruker jeg indeksen til å regne med tilbake til den faktiske temperaturen.

 

PS: har ikke testet koden, så det kan være feil i den, men vil tru at dette skal gi et mye bedre resultat enn hva du hadde i utgangspunktet (om jeg ikke har gjort noen alvorlig tabber her da... litt sliten i hode i dag...)

Lenke til kommentar

 

 

det er vel strengt tatt det jeg har gjort, men da vil jeg bare få målinger fra ca 10 til 40 grader, noe som er for lite målbart område...

hvis jeg får det til, kan det hende at jeg trapper hele sensoren i kjøleblokka på bilen, og der må jeg vite om det er 41 grader eller 91 grader, noe som ikke går med dagens oppsett om du skjønner =)

 

 

Så vidt jeg kan se så vil koden du har skrevet gi deg 10 grader hvis ADCen (sensorValue) returnerer 0, og 40 grader om ADCen returnerer 1023, noe som er helt feil. sensorValue vil heller aldri være mindre enn 10 eller høyere enn 40 etter map funksjonen (om jeg har tippet dens funksjonalitet rett), så if-else her er litt bortkastet.

 

Her er noe jeg mener er mer korrekt:

 

static const uint16_t adctmp[] PROGMEM= 
{1012, 1006, 999, 988, 977,
 960, 939, 913, 880, 842, 
 797, 747, 691, 633, 572, 
 512, 453, 398, 346, 299,
 257, 221, 189, 161, 137,
 117, 100, 87, 73, 64, 
 54, 48, 42, 36, 30};

int getTemp(){
uint16_t* ptr = &adctmp;; //pointer to lookup table in flash
uint16_t adcval = analogRead(sensorPin); // read analog value
uint16_t idx = 0;
uint16_t tmp0, tmp1;
uint16_t temp, temp0, temp1;
//search through table looking for closest fit
tmp0 = pgm_read_byte(*ptr++);
while(adcval < tmp0){
	tmp1 = tmp0;
	tmp0 = pgm_read_byte(*ptr++);
	idx++;
}
//calculate the two temperatures (5 degrees per index in the table)
temp1 = ((idx-1)*5)-50; //lower limit 
//temp0 = ((idx)*5)-50;   //higher limit
//interpolate between these two
temp = temp1 + ((5*(tmp1-adcval))/(tmp1-tmp0));
//return final value
return temp;
}

 

 

Her har jeg først tatt tallene fra databladet og lagt inn i et spreadsheet (XL) dokument og lagt til de 5 graders intervallene som manglet (lineært interpolert). Så regnet jeg ut hva spenningen vil være ved de forskjellige temperaturene, og fant etter det den tilhørende ADC koden. Jeg kan da se at du skal kunne ha ca 0.5 grader oppløsning om jeg ikke har gjort noe feil. Tok så tallene for ADC kode og la inn i tabellen her, og så bruker jeg indeksen til å regne med tilbake til den faktiske temperaturen.

 

PS: har ikke testet koden, så det kan være feil i den, men vil tru at dette skal gi et mye bedre resultat enn hva du hadde i utgangspunktet (om jeg ikke har gjort noen alvorlig tabber her da... litt sliten i hode i dag...)

 

 

hvordan skal jeg da gjøre det med spenningsdeleren? nå er termistoren 20k@25C, så skal jeg bare beholde 20k-en på andre siden, eller bør jeg endre verdien?

 

EDIT: målte motstanden på andre siden... den var 19,64k

Endret av haavardgj
Lenke til kommentar

 

 

det er vel strengt tatt det jeg har gjort, men da vil jeg bare få målinger fra ca 10 til 40 grader, noe som er for lite målbart område...

hvis jeg får det til, kan det hende at jeg trapper hele sensoren i kjøleblokka på bilen, og der må jeg vite om det er 41 grader eller 91 grader, noe som ikke går med dagens oppsett om du skjønner =)

 

 

Så vidt jeg kan se så vil koden du har skrevet gi deg 10 grader hvis ADCen (sensorValue) returnerer 0, og 40 grader om ADCen returnerer 1023, noe som er helt feil. sensorValue vil heller aldri være mindre enn 10 eller høyere enn 40 etter map funksjonen (om jeg har tippet dens funksjonalitet rett), så if-else her er litt bortkastet.

 

Her er noe jeg mener er mer korrekt:

 

static const uint16_t adctmp[] PROGMEM= 
{1012, 1006, 999, 988, 977,
 960, 939, 913, 880, 842, 
 797, 747, 691, 633, 572, 
 512, 453, 398, 346, 299,
 257, 221, 189, 161, 137,
 117, 100, 87, 73, 64, 
 54, 48, 42, 36, 30};

int getTemp(){
uint16_t* ptr = &adctmp;; //pointer to lookup table in flash
uint16_t adcval = analogRead(sensorPin); // read analog value
uint16_t idx = 0;
uint16_t tmp0, tmp1;
uint16_t temp, temp0, temp1;
//search through table looking for closest fit
tmp0 = pgm_read_byte(*ptr++);
while(adcval < tmp0){
	tmp1 = tmp0;
	tmp0 = pgm_read_byte(*ptr++);
	idx++;
}
//calculate the two temperatures (5 degrees per index in the table)
temp1 = ((idx-1)*5)-50; //lower limit 
//temp0 = ((idx)*5)-50;   //higher limit
//interpolate between these two
temp = temp1 + ((5*(tmp1-adcval))/(tmp1-tmp0));
//return final value
return temp;
}

 

 

Her har jeg først tatt tallene fra databladet og lagt inn i et spreadsheet (XL) dokument og lagt til de 5 graders intervallene som manglet (lineært interpolert). Så regnet jeg ut hva spenningen vil være ved de forskjellige temperaturene, og fant etter det den tilhørende ADC koden. Jeg kan da se at du skal kunne ha ca 0.5 grader oppløsning om jeg ikke har gjort noe feil. Tok så tallene for ADC kode og la inn i tabellen her, og så bruker jeg indeksen til å regne med tilbake til den faktiske temperaturen.

 

PS: har ikke testet koden, så det kan være feil i den, men vil tru at dette skal gi et mye bedre resultat enn hva du hadde i utgangspunktet (om jeg ikke har gjort noen alvorlig tabber her da... litt sliten i hode i dag...)

 

 

hvordan skal jeg da gjøre det med spenningsdeleren? nå er termistoren 20k@25C, så skal jeg bare beholde 20k-en på andre siden, eller bør jeg endre verdien?

 

EDIT: målte motstanden på andre siden... den var 19,64k

 

bare behold den andre motstanden på 20K, det er det jeg har brukt i mine beregninger her. trur ikke avviket skal ha så mye betydning. Har lagt ved regnearket mitt (openoffice format), hvis du vil se litt på det.

ntc.zip

Lenke til kommentar

Hei

har en teat NTC 20 termistor, som jeg vil lese av med arduinoen. den er 20k ohm ved 25C. jeg prøvde å lage en spenningsdeler:

 

 

Hva med å bruke en DS18B20 temperatur sensor ?

Ligger en enkel men bra tutorial her

 

http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

nå var jo tanken å bruke det jeg allerede hadde... siden jeg har en 3-4 stykk, og de er av industriell standard, er det enklere (og billigere) enn å begynne å kjøpe inn noe som ikke har den beskyttelsesgraden. samtidig har jeg alt som trengs for å montere sånne sensorer, så da blir det bedre enn en DIY-løsning.

 

men, takk for guiden

Lenke til kommentar

nå var jo tanken å bruke det jeg allerede hadde... siden jeg har en 3-4 stykk, og de er av industriell standard,

 

Skjønner :)

Men DS18B20 er verdt å se på, også for andre arduino interesserte.

Fordelen er att man kan ha mange sensorer på samme linje.

 

1wirebus.gif

Lenke til kommentar

Med god koding, hvilken er mest strømgjerrig av Arduino uno og texas instr. MSP430...?

(er de to jeg har hjemme nå)

 

Skal bygge et prosjekt som skal være batteridrevet, med lang batterilevetid, å lurer på om jeg ikke skal bruke Texas i stede, har intrykk av at Texas er svært så strømgjerrig i.f.t.?

Om jeg klarer å bruke strømspare modus 4 også så er det vel ingen tvil??

 

(Har ikke spesielt bred erfaring med dette, kanksje svaret er så innlysende at det er idiot-spørsmål :whistle: )

Lenke til kommentar

Med god koding, hvilken er mest strømgjerrig av Arduino uno og texas instr. MSP430...?

(er de to jeg har hjemme nå)

 

Skal bygge et prosjekt som skal være batteridrevet, med lang batterilevetid, å lurer på om jeg ikke skal bruke Texas i stede, har intrykk av at Texas er svært så strømgjerrig i.f.t.?

Om jeg klarer å bruke strømspare modus 4 også så er det vel ingen tvil??

 

(Har ikke spesielt bred erfaring med dette, kanksje svaret er så innlysende at det er idiot-spørsmål :whistle: )

 

Se her:

 

Arduino sleep

 

eller her:

Arduino Sleep 2

Lenke til kommentar

Hei

 

har en lcd-skjerm, og noen knapper, der jeg har laget til en slags meny for å styre utganger, og vise hva jeg slår på/av, men jeg har litt problemer med auto-funksjonen jeg prøver å lage...

 

her er deler av koden:

 

// feedback to have auto on
const byte ftrunk = 7; 
const byte fbacklight = 5;
const byte fxlight = 3;

// menu
byte updateit = 10;  // update the lcd
byte menu = 0;       // menu level 
int scrolling = 0;   // scroll between the firmware text 
int sysdelay = 50;   // delay for update freq.

// outputs
byte xlight = 2;      
byte backlight = 4;       
byte trunk = 6;     


// modes for menu, Standard output

// 0 - off, 1 - on, 2 - auto
byte mode0 = 0;
byte mode1 = 2;
byte mode2 = 2;
byte mode3 = 2;
byte mode4 = 0;
byte mode5 = 0;
byte mode6 = 1;

void Setup()
// feedback pin
pinMode(fbacklight, INPUT);  digitalWrite(fbacklight, LOW);
pinMode(backlight, OUTPUT); // light

void out()

 if (mode2 == 0){
   digitalWrite (backlight, LOW);
 }
 if (mode2 == 1){
   digitalWrite (backlight, HIGH);
 }
 if (mode2 == 2){
   if (fbacklight == HIGH){
     digitalWrite (backlight, HIGH);
   }
   if (fbacklight == LOW){
     digitalWrite (backlight, LOW);
   }
 }


 

det som er problemet, er at når jeg slår av eller på, funker det fint. men når jeg setter den til auto, er den konstant på, uansett om inputen er høy eller lav...

 

noen som ser om jeg har gjort noen feil?

Endret av haavardgj
Lenke til kommentar

Men hvor mye strøm drar Arduino'en i sleep da? Det ser ut til at Uno har andre spenningsregulatorer enn 7805, som jo var ankepunktet tidligere.

MSP430 drar kun 1 mikroA ifølge Wikipedia.

 

It uses about 19 mA when awake (some of which would be the LED) but only 25 uA (0.025 mA) when asleep. 25 uA isn't much, and would not drain your battery very quickly.

er ikke sikker på om det er så store forskjeller, mellom duemilanove'n eller unoen...

 

evt, kan du jo lage deg en standalone arduino, og bruke en spenningsregulator som bruker minst mulig strøm i idle...

Endret av haavardgj
Lenke til kommentar

Men hvor mye strøm drar Arduino'en i sleep da? Det ser ut til at Uno har andre spenningsregulatorer enn 7805, som jo var ankepunktet tidligere.

MSP430 drar kun 1 mikroA ifølge Wikipedia.

Bra svaret ikke nødvendigvis er så innlysende.. :whistle:

 

Den nederste linken fra haavard sier følgende om Arduino sleep

It uses about 19 mA when awake (some of which would be the LED) but only 25 uA (0.025 mA) when asleep.

Men det står ingen steder at det er snakk om uno eller om tallene er bekreftet...

 

Så jeg tror kanksje 430 får lov til å være med på dette prosjektet, betydelig billigere (i tilfelle havari, skal ut i kulde), trolig mindre strømtrekk å nok av funksjoner...

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...