muddy
Magnetische flux loopt altijd in gesloten paden, elektrische stroom niet per se (volgens de wet van Ampère), want: elektrische lading kan ophopen.
Hoi,
ik wil beginnen met het inlezen van analoge waardes op mijn ATMEGA8 op 16MHz.
Na een zoektocht heb ik een begrijpelijke tutorial gevonden. Opzich snap ik in grote lijnen wel wat er gebeurt, alleen nog wat vraagjes:
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
Waarom kan ik niet zeggen: ADEN=1 etc.? Is dat omdat de AVR 'ADCSRA' wel fysiek kent, maar 'ADEN' niet?
Op bovenstaande manier wordt de sample frequentie ingesteld, in dit geval 16M / 128 = 125KHz. Ik wil in mijn ontwerp 2 ADC's uitlezen op minimaal 20Hz, een bipolaire stepper op max 3000 steps/sec aansturen en een op max 6000 steps/sec. Is het dan verstandig om de ADC op minder dan 125KHz uit te lezen, of is dat onmogelijk?
Bovendien: ik wil 20x per seconde de snelheid van beide steppers aanpassen aan de hand van de ADC waardes. Hoe moet ik tegelijk continu twee steppers op verschillende snelheden laten draaien, twee ADC waardes inlezen en die berekenen? Ik heb iets gehoord over threaden, maar hoe werkt dat?
Als ik vaag ben wil ik dat graag weten.
Tom
Hee TomTom
De samplefrequentie is de adc klok gedeeld door 13, 125kHz/13 dus. Je moet de adc klok niet boven de 1MHz laten komen, dus je kan maximaal 80ksps doen, 2 adc's op 40ksps.
Echoflex
1
ADEN = 1 kan niet omdat ADEN niets anders is dan een positie in het ADCSRA register. ADEN is een definitie van een nummer (bijvoorbeeld #define ADEN 7)
(1<<ADEN) set het bitje op positie 7 op 1.
plantrekker
True story bro!
Op 16 augustus 2009 20:17:37 schreef muddy:
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
Waarom kan ik niet zeggen: ADEN=1 etc.?
ADCSRA is het register waarvan je bepaalde bits wil setten. Kijk daarvoor zeker eens naar de datasheet p207!
ADEN ziet de compiler als een getal, in dit geval is dat 7. Dus: (1<<ADEN) wil zeggen, shift de laagste bit(1 dus) 7 plaatsen naar links. Je kan dit bvb ook vervangen door het getal 128 maar daarmee ziet niemand direct wat het betekent. Deze notatie wordt dus gebruikt omdat je direct ziet wat je doet.
At compile time, wordt er van "=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)" dus gewoon een getal gemaakt.
Op bovenstaande manier wordt de sample frequentie ingesteld, in dit geval 16M / 128 = 125KHz. Ik wil in mijn ontwerp 2 ADC's uitlezen op minimaal 20Hz, een bipolaire stepper op max 3000 steps/sec aansturen en een op max 6000 steps/sec. Is het dan verstandig om de ADC op minder dan 125KHz uit te lezen, of is dat onmogelijk?
De frequentie die je instelt is de clock voor de ADC module. Een convertie is klaar na 13 van die clocks. De frequentie bepaalt dus enkel hoe snel de convertie gebeurt. Hoeveel converties per seconde je doet heeft hier niets mee te maken (onrechtstreeks wel, hoe sneller, hoe meer je er zal kunnen doen natuurlijk)
Vanaf een frequentie van 1MHz is je nauwkeurigheid kleiner dan 8 bit.
Hoe moet ik tegelijk continu twee steppers op verschillende snelheden laten draaien, twee ADC waardes inlezen en die berekenen?
Door juist te kiezen wat je in je main loop doet en wat je via interrupts zal doen. Interrupts onderbreken je main loop, handelen iets af (bvb de adc converties) en laten nadien de main loop weer verder doen.
muddy
Magnetische flux loopt altijd in gesloten paden, elektrische stroom niet per se (volgens de wet van Ampère), want: elektrische lading kan ophopen.
Ah, nu snap ik het een beetje, ik had ook verkeerd gelezen.
Ik dacht: shift ADEN met 1 plaats naar links, en dacht WTF. Het moet dus zijn: shift 1 met ADEN (dus 7) plaatsjes naar links).
Nog iets:
//Select ADC Channel ch must be 0-7
ch=ch&0b00000111;
ik neem aan dat de drie enen op het einde staan voor 7?
Ik snap nu hoe ik tijdens het aansturen van een stepper ADC waardes kan inlezen, met die interrupts, maar nog niet hoe ik twee steppers op verschillende snelheden tegelijk aan kan sturen. Want je krijgt dan toch twee loops:
pinnetje van motor 1 hoog, wacht even, ander pinnetje hoog etc,
pinnetje van motor 2 hoog, wacht net iets langer, ander pinnetje hoog etc. En ik zie niet hoe ik die loops tegelijk kan laten draaien.
plantrekker
True story bro!
ch=ch&0b00000111 staat idd voor kanaal 7.
Datasheet p205:
ADMUX bits 3:0 - MUX3:0: Analog Channel Selection Bits:
0000 ADC0
0001 ADC1
. .
. .
0110 ADC6
0111 ADC7Je leest toch beter eens de delen van de datasheet met betrekking op jouw toepassing. Lees eens alles over de ADC module van de AVR. Het is maar 14 blz. en je zal er veeel aan hebben.
Hoe je steppers aangestuurd moeten worden weet ik niet dus kan weinig zeggen over hoe je best je main loop en interrupts implementeert.
Timer's gebruiken? Zodra de motor 1 hoog wordt een timer starten, en dan in de interrupt je andere hoog maken. Voor die ander hetzelfde maar dan met een andere timer. Door een offset in de timer te zetten kan je de wachttijd voor een interrupt beinvloeden.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Ja binary 000000000111 is 7 in decimaal, hex, en octaal.
Tja, twee steppers op verschillende snelheden is lastig. Je kunt bijhouden wanneer je weer iets moet doen met beide steppers.
while (1) {
time_to_sleep = min (sleep1, sleep2);
sleep (time_to_sleep);
sleep1 -= time_to_sleep;
sleep2 -= time_to_sleep;
if (!sleep1) {
// Doe iets met motor1
....
sleep1 = ...; / *tijd om te wachten voor motor1.
}
if (!sleep2) {
// Doe iets met motor2
....
sleep2 = ...; / *tijd om te wachten voor motor2.
}
}
Dit is dan met sleeps in het hoofdprogramma, maar iets dergelijks kun je maken op basis van interrupts.
Erelce
**** De beschikbare ruimte van een werkplek is omgekeerd evenredig met de grootte van deze werkplek **** AVR-Oefeningen op Electronics 4 Fun
een tijdje geleden heb ik ook zoiets gemaakt
voor 2 hardware PWM's ziet het er ongeveer zo uit in assembly...
(meer details kun je vinden op mijn site)
...
Start_ADC:
ldi Input,32 ;ADLAR + ADC0 > 0b00100000 = 32 decimaal
Next_Input:
out ADMUX,Input
in temp,ADCSR
sbr temp,(1<<ADSC); aanleggen startbit ADSC
out ADCSR,temp
Busy:
sbic ADCSR,ADSC ;wachten tot startbit ADSC 0 wordt
rjmp Busy
cpi Input,32 ;ADLAR + ADC0 > 0b00100000 = 32 decimaal
breq Laden_OCR1A
cpi Input,33 ;ADLAR + ADC1 > 0b00100001 = 33 decimaal
breq Laden_OCR1B
rjmp Start_ADC
Laden_OCR1A:
in temp,ADCH
out OCR1A,temp
inc Input
rjmp Next_Input
Laden_OCR1B:
in temp,ADCH
out OCR1B,temp
rjmp Start_ADC
.exit