Droppdetektor
Re: Droppdetektor
I ditt fall har du en specifik uppgift du ska/vill lösa.
Kolla om ATmega'n har hårdvara till att lösa uppgiften, har den inte kan du leta efter en som har.
Kolla om ATmega'n har hårdvara till att lösa uppgiften, har den inte kan du leta efter en som har.
- Swech
- EF Sponsor
- Inlägg: 4694
- Blev medlem: 6 november 2006, 21:43:35
- Ort: Munkedal, Sverige (Sweden)
- Kontakt:
Re: Droppdetektor
Vad är det för noggranhet som du behöver på din 20us mätning.
10% ger ju 22us eller är det 20.00us som du vill ha?
Swech
10% ger ju 22us eller är det 20.00us som du vill ha?
Swech
Re: Droppdetektor
Jo, så är det.
Men klockan kan med PLL komma upp i 64Mhz det borde betyda att man kan få en upplösning på klockan på ca 160ns. De CCP moduler som jag jobbat med brukar flytta värdet på klockan till ett register som kan läsas av i efterhand av ett interrupt.
När interruptet kommer får man göra sina felkontroller.
Därför är jag inte så fasligt orolig över att tidtagningen kommer krångla. Men jag skulle inte vilja hamna i fallet då interruptet tar för lång tid på sig innnan nästa interrupt kommer. Då kommer man ganska snart få stack overflow (vet ifs inte om den klarar nästlade interrupt). Eller att USB enheten (CDC) hittar på grejjer som behöver processorkraft och förstör allt.
jag känner att jag har hyfsad koll på lösningsförslaget. Det är vägen till implementering som är min största fundering.
Men klockan kan med PLL komma upp i 64Mhz det borde betyda att man kan få en upplösning på klockan på ca 160ns. De CCP moduler som jag jobbat med brukar flytta värdet på klockan till ett register som kan läsas av i efterhand av ett interrupt.
När interruptet kommer får man göra sina felkontroller.
Därför är jag inte så fasligt orolig över att tidtagningen kommer krångla. Men jag skulle inte vilja hamna i fallet då interruptet tar för lång tid på sig innnan nästa interrupt kommer. Då kommer man ganska snart få stack overflow (vet ifs inte om den klarar nästlade interrupt). Eller att USB enheten (CDC) hittar på grejjer som behöver processorkraft och förstör allt.
jag känner att jag har hyfsad koll på lösningsförslaget. Det är vägen till implementering som är min största fundering.
Re: Droppdetektor
Eller att arduion miljön lägger till extra grejjer för att förenkla t.ex debugging eller att kompilatorn ger ineffektiv kod. Jag spekulerar bara kring ev problem, ville höra med någon som använt sig av miljön för att se för/nackdelar.
Re: Droppdetektor
Arduino hårdvara ska gå att utveckla med AVR studio och då är det riktig C/C++ och inte Wire.
Re: Droppdetektor
Glömde att ironi och sarkasm inte alltid framgår så tydligt.Icecap skrev:Wedge: ...
Men du har såklart all rätt att ha den åsikt.
Re: Droppdetektor
Wedge: Ska jag förstå det som att du lägger ord i min mun? Ord som du inte har belägg för och som kommer från dig?
Senast redigerad av Icecap 1 april 2015, 19:06:40, redigerad totalt 1 gång.
Re: Droppdetektor
Plattformskrig är kul inom rimliga gränser. Har varit med sedan zx spectrum vs C=64.
Personligen tycker jag Arduino är helt ok att börja med om man är osäker på om elektronik är något man vill hålla på med eller ej. Antingen fortsätter man tills man stöter på begränsningar och då blir man tvungen att utveckla sig eller slänga det på hyllan.
Skall du programmera kompatibelt med Arduino standarden och sätta 8 bitar på en IO port, lär du mig veterligt köra digitalWrite kommandot 8 ggr, och då börjar vi snacka bortkastade klockcykler. Du kan skita i arduino standarden och köra direkt mot PORTB, men då måste du först tänka igenom pinouten som inte stämmer med Atmegas "original pinout" och då är du iaf körd om du skall använda koden från Uno till Mega eller någon annan Arduino med annan intern pinout på chipet.
Sedan får du ju tänka lite logistiskt. Du kan ha en 2GHz microcontroller och ändå fucka upp saker om du t.ex använder mjukvaruserial eller LCD med blockande funktioner. Det tar c.a. 40us att skicka tecken till en standard LCD iomed att du måste vänta den tiden innan LCDn godtar ett nytt tecken. Du snackade en vattendroppe var 20e us vilket skulle betyda att du missar varannan droppe om du enbart skrivet *ett* tecken, ännu fler om du skall skriva ut en sträng.
Nu vet jag inte vad du skall göra mellan varje droppe men detta är ju lite saker man bör fundera på när det gäller tidskritiska funktioner.
EDIT: Nedan har du en länk som förklarar fördelar och nackdelar med att gå direkt på metallen gällande IO-portar.
http://www.arduino.cc/en/Reference/PortManipulation
Personligen tycker jag Arduino är helt ok att börja med om man är osäker på om elektronik är något man vill hålla på med eller ej. Antingen fortsätter man tills man stöter på begränsningar och då blir man tvungen att utveckla sig eller slänga det på hyllan.
Mig veterligt läggs ingenting till för att förenkla debugging i sig, däremot för att förenkla utveckling. De flesta bibliotek är beroende av kompatibilitet mellan de olika Aurdino plattformarna och hårdvaran. Speciellt pinouten. De blir följaktligen lite segare än om man bangar hårdvaran direkt. Typ digitalwrite() vs PORTB |= 0x10101010 där digitalWrite tar betydligt längre tid och dessutom enbart sätter 1 bit medans PORTB |= 0x10101010 sätter 8 bitar i ett svep.dangraf skrev:Eller att arduion miljön lägger till extra grejjer för att förenkla t.ex debugging eller att kompilatorn ger ineffektiv kod. Jag spekulerar bara kring ev problem, ville höra med någon som använt sig av miljön för att se för/nackdelar.
Skall du programmera kompatibelt med Arduino standarden och sätta 8 bitar på en IO port, lär du mig veterligt köra digitalWrite kommandot 8 ggr, och då börjar vi snacka bortkastade klockcykler. Du kan skita i arduino standarden och köra direkt mot PORTB, men då måste du först tänka igenom pinouten som inte stämmer med Atmegas "original pinout" och då är du iaf körd om du skall använda koden från Uno till Mega eller någon annan Arduino med annan intern pinout på chipet.
Sedan får du ju tänka lite logistiskt. Du kan ha en 2GHz microcontroller och ändå fucka upp saker om du t.ex använder mjukvaruserial eller LCD med blockande funktioner. Det tar c.a. 40us att skicka tecken till en standard LCD iomed att du måste vänta den tiden innan LCDn godtar ett nytt tecken. Du snackade en vattendroppe var 20e us vilket skulle betyda att du missar varannan droppe om du enbart skrivet *ett* tecken, ännu fler om du skall skriva ut en sträng.
Nu vet jag inte vad du skall göra mellan varje droppe men detta är ju lite saker man bör fundera på när det gäller tidskritiska funktioner.
EDIT: Nedan har du en länk som förklarar fördelar och nackdelar med att gå direkt på metallen gällande IO-portar.
http://www.arduino.cc/en/Reference/PortManipulation
Re: Droppdetektor
LCD-skrivning lägger man på oprioriterad bakgrundsnivå, i loop(). Och så fångar man droppar på interruptnivå.
Re: Droppdetektor
Precis, i de flesta fall t.ex om man skall man räkna droppar eller liknande är det smidigaste interrupt. Beror som sagt på vad som skall utföras mellan varje droppe. Han skrev något om felkontroll m.m. så det beror väl på hur lång den kodslingan blir.
Kör man en arduino i 16MHz så blir det ju 20*16 = 320 instruktionscykler mellan varje droppe och om varje maskinkodsinstruktion tar mellan 1-3 instruktionscykler så hinner man ju klämma in en del kod. Skall man köra med komplexa beräkningar får man väl steppa upp till en 16/32 bitars uC som har HW multiplicering och division av större tal, typ Teensy eller 16/32 bitars PIC.
Möjligt att det funkar klockrent med Arduino och lite smart programmering också.
Kör man en arduino i 16MHz så blir det ju 20*16 = 320 instruktionscykler mellan varje droppe och om varje maskinkodsinstruktion tar mellan 1-3 instruktionscykler så hinner man ju klämma in en del kod. Skall man köra med komplexa beräkningar får man väl steppa upp till en 16/32 bitars uC som har HW multiplicering och division av större tal, typ Teensy eller 16/32 bitars PIC.
Möjligt att det funkar klockrent med Arduino och lite smart programmering också.
Re: Droppdetektor
Tack!
Då börjar jag förstå lite mer. Bra att veta att man kan köra arduino i avr studio. Jag får grotta ner mig lite mer i vad jag behöver och välja plattform.
Mvh/
Daniel
Då börjar jag förstå lite mer. Bra att veta att man kan köra arduino i avr studio. Jag får grotta ner mig lite mer i vad jag behöver och välja plattform.
Mvh/
Daniel
Re: Droppdetektor
Det bästa med Arduino är att man kan köpa en på lunchen, koppla in den med USB i sin Mac/Win/Linux-dator, skriva några rader och sedan är det klart. För vissa typer av enkla engångsproblem är det svårslaget.
Re: Droppdetektor
var ju bara tvungen att testa det , och det tog mindre är 30 minuter att mäta pulstid, och då var ju 20 minuter googlande
hittade denna kod , url i kommentaren.
Men efter att ha läst igenom det finner jag det inte helt osannolikt
Det skulle alltså bli lite tajt att hinna skriva om det och äta upp lunchen på en timme
hittade denna kod , url i kommentaren.
Provade bara med en enkel tryckknapp på pin 8 , och med lite olika prescaler inställningar, så jag har ingen aning om det räknar rätt.//
// http://arduino.cc/forum/index.php/topic,97451.0.html
//
#include <io.h>
#include <interrupt.h>
volatile uint16_t T1Ovs1, T1Ovs2; //OVERFLOW COUNTERS
volatile uint16_t Capt1, Capt2, Capt3; //VARIABLES TO HOLD TIMESTAMPS
volatile uint8_t Flag; //CAPTURE FLAG
float deltatime;
#define icpPin 8 // PB0 ICP D8 Interrupt input
/*--------------------------------------------------------------------------------------------------
INTIALIZING TIMER
---------------------------------------------------------------------------------------------------*/
void InitTimer1(void)
{
TCNT1=0; //SETTING INTIAL TIMER VALUE
TCCR1B|=(1<<ICES1); //SETTING FIRST CAPTURE ON RISING EDGE ,(TCCR1B = TCCR1B | (1<<ICES1)
TIMSK1|=(1<<ICIE1)|(1<<TOIE1); //ENABLING INPUT CAPTURE AND OVERFLOW INTERRUPTS
}
/*--------------------------------------------------------------------------------------------------
STARTING TIMER
---------------------------------------------------------------------------------------------------*/
void StartTimer1(void)
{
// TCCR1B|=(1<<CS10); //STARTING TIMER WITH PRESCALER 1
TCCR1B|=(1<<CS11)|(1<<CS10); //STARTING TIMER WITH PRESCALER 64
// TCCR1B|=(1<<CS12); //STARTING TIMER WITH PRESCALER 256
// TCCR1B|=(1<<CS12)|(1<<CS10); //STARTING TIMER WITH PRESCALER 1024
sei(); //ENABLING GLOBAL INTERRUPTS
}
/*--------------------------------------------------------------------------------------------------
CAPTURE ISR
---------------------------------------------------------------------------------------------------*/
ISR(TIMER1_CAPT_vect)
{
// TCNT1 = 0;
if (Flag==0)
{
Capt1=ICR1; //SAVING CAPTURED TIMESTAMP
TCCR1B&=~(1<<ICES1); //CHANGE CAPTURE ON FALLING EDGE
T1Ovs2=0; //RESETING OVERFLOWS
//digitalWrite(13, HIGH); // set the LED on
//delay(100); // wait for a second
}
if (Flag==1)
{
Capt2=ICR1; //SAVING CAPTURED TIMESTAMP
TCCR1B|=(1<<ICES1); //CHANGING CAPTURE ON RISING EDGE
T1Ovs1=T1Ovs2; //SAVING FIRST OVERFLOW COUNTER
//digitalWrite(13, LOW); // set the LED off
//delay(100); // wait for a second
}
if (Flag==2)
{
Capt3=ICR1; //SAVING CAPTURED TIMESTAMP
TIMSK1&=~((1<<ICIE1)|~(1<<TOIE1)); //STOP INPUT CAPTURE AND OVERFLOW INTERRUPTS
//digitalWrite(13, HIGH); // set the LED on
//delay(100); // wait for a second
}
Flag++; //INCREMENTING FLAG
}
/*--------------------------------------------------------------------------------------------------
OVERFLOW ISR
---------------------------------------------------------------------------------------------------*/
ISR(TIMER1_OVF_vect)
{
T1Ovs2++;//INCREMENTING OVERFLOW COUNTER
}
/*--------------------------------------------------------------------------------------------------
MAIN FUNCTION
---------------------------------------------------------------------------------------------------*/
int main(void)
{
volatile uint8_t FINALTIME; //VARIABLE TO HOLD THE FINAL TIME
pinMode(icpPin,INPUT);
digitalWrite(icpPin,HIGH); //pull up
// pinMode(13, OUTPUT);
InitTimer1(); //CALLING FUNCTION INITTIMER1 TO INITIALIZE TIMER 1
StartTimer1(); //CALLING FUNCTION STARTTIMER1 TO START TIMER 1
while(1)
{
//calculate duty cycle if all timestamps captured
if (Flag==3)
{
Serial.begin(115200);
Serial.print("\r");
Serial.print(" <Capture1>:");
Serial.print(Capt1);
Serial.print(" <Capture2>:");
Serial.print(Capt2);
Serial.print(" <Capture3>:");
Serial.print(Capt3);
Serial.print(" <OVL1>:");
Serial.print(T1Ovs1);
Serial.print(" <OVL2>:");
Serial.print(T1Ovs2);
Serial.print("\n");
Serial.print("<FINAL TIME>:");
deltatime = (Capt3-Capt1)*0.004 ; // Prescaler 64
// deltatime = (Capt3-Capt1)*0.016; // Prescaler 256
Serial.print((float)deltatime);
Serial.print(" Millisecond");
Serial.print("\n");
Flag=0; //CLEARING FLAG
T1Ovs1=0; //CLEARING OVERFLOW COUNTERS
T1Ovs2=0;
TIFR1=(1<<ICF1)|(1<<TOV1); //CLEARING INTERRUPT FLAGS TO AVOID ANY PENDING INTERRUPTS
TIMSK1|=(1<<ICIE1)|(1<<TOIE1); //ENABLING INPUT CAPTURE AND OVERFLOW INTERRUPTS
TCNT1 = 0;
}
}
}
Men efter att ha läst igenom det finner jag det inte helt osannolikt
Det skulle alltså bli lite tajt att hinna skriva om det och äta upp lunchen på en timme