AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörjare

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
tokfan
Inlägg: 694
Blev medlem: 10 juni 2010, 14:05:13

AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörjare

Inlägg av tokfan »

Hej!

Jag är nybörjare och har just börjat trixa med ADC.

Kan inget om interupts ännu.
Mitt mål är att i slutändan kunna läsa av två pinnar om det är 2,5V eller 0V samtidigt.

Detta går ju inte på vanliga I/O portar om man matar ATMEGAn med 5V.

Jag labbar nu med basic kod men vet att jag är ute och cyklar.
Finns det något simpelt sätt för en nybörjare att lösa detta?

Just nu har jag kopplat upp 8 dioder på en labplatta och anslutit fotoresistorer till ADC0 och ADC4.
Om spänningen går lägre än 2,5V (ADC=500) på någon av fotoresistorerna ska de första eller sista 4 dioderna tändas beroende på vilken ADC-pinne som sjunker i spänning.


tips?
Här är mitt misslyckade försök:

Kod: Markera allt

#include <avr/io.h>
#include <util/delay.h>

// ----------------Functions-------------------------------------------------
static inline void initADC4(void)
{
	ADMUX |= (1<< REFS0)|(1<< MUX2);
	ADCSRA |= (1<< ADPS1) | (1<< ADPS0);
	ADCSRA |= (1<< ADEN);
}

static inline void initADC0(void)
{
	ADMUX |= (1<< REFS0);
	ADCSRA |= (1<< ADPS1) | (1<< ADPS0);
	ADCSRA |= (1<< ADEN);
}

int main(void)
{
	
	DDRD = 0xFF;
	
	uint16_t adc4Value;
	uint16_t adc0Value;
	
	while (1)
	{
		initADC4();
		ADCSRA |= (1<< ADSC);
		loop_until_bit_is_clear(ADCSRA, ADSC);
		adc4Value = ADC;
		
		
		PORTD = 0;
		
		
		
		initADC0();
		
		ADCSRA |= (1<< ADSC);
		loop_until_bit_is_clear(ADCSRA, ADSC);
		adc0Value = ADC;
		
		if(adc0Value < 500)
		{
			PORTD |= 0xF0;
		}
		
		if(adc4Value < 500)
		{
			PORTD |= 0x0F;
		}
		_delay_ms(100);
		
		
	}
	return (0);
}



Tar gärna emot alla tips som finns för att utvecklas.
Ha en bra dag!
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av Icecap »

Nu är det ju Arduino-skitens speciella språk men jag ser omedelbart ett fel:
Du initierar A/D-omvandlaren konstant (iaf. kallar InitADCx).

Korrekt sätt är att initiera A/D-omvandlaren i setup (eller vad skiten heter i Arduino), alltså i starten - och då bara 1 gång.

Sedan väljer man vilken ingång som ska omvandlas, startar en omvandling och - utan interrupt - väntar till en omvandling är utförd.

När detta är gjort sparar man värdet från den ingång, väljer nästa ingång och gör samma sak (starta omvandling, vänta på att den är klar och spara värdet).

Nu är båda ingångar mätta och du kan välja vad som ska tändas.

Jag ser en logisk fälla i ditt urval: vad ska ske om BÅDA ingångar är under 2,5V?
I övrigt är 2,5V vid AD-värde 512.

Du släcker i övrigt hela port D för varje varv, om det är tillsiktad anser jag vara tveksamt. Den ska nollställas samtidig som A/D-omvandlaren initieras (och därmed bara 1 gång) och sedan bör den väl stå kvar som den är sedan senaste omvandling.
Användarvisningsbild
AndLi
Inlägg: 17050
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av AndLi »

Då atmegan bara har ett ADC block kommer du aldrig kunna läsa av de samtidigt. Men tiden mellan två följande avläsningar på två olika pinnar kan bli mycket kort, men inte samtidig...
Janson1
Inlägg: 1338
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av Janson1 »

Testade lite och fick till vad jag tror du vill ha, nu är ju detta "skitArduino" (men det är det enda jag kan och har förövrigt lyckats bra, över förväntan på mina projekt...) Du vill ha att fyra lysdioder skall tändas samtidigt men jag gjorde bara en utgång per analog ingång, om du vill så är det bara att trippla utgångarna.

Kod: Markera allt

int ut1 = 10;
int ut2 = 11;
int value1;
int value2;



void setup() 
{
 pinMode(ut1, OUTPUT);
 pinMode(ut2, OUTPUT);

}

void loop() 
{
  value1 = analogRead(A0);
  value2 = analogRead(A1);

  if(value1 <= 512)
   {
    digitalWrite(ut1, HIGH);
   }
   else 
    {
    digitalWrite(ut1, LOW);
    }

  if(value2 <= 512)
   {
    digitalWrite(ut2, HIGH);
   }
   else 
    {
    digitalWrite(ut2, LOW);
    }
} //slut
tokfan
Inlägg: 694
Blev medlem: 10 juni 2010, 14:05:13

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av tokfan »

Icecap skrev:Nu är det ju Arduino-skitens speciella språk men jag ser omedelbart ett fel:
Du initierar A/D-omvandlaren konstant (iaf. kallar InitADCx).

Korrekt sätt är att initiera A/D-omvandlaren i setup (eller vad skiten heter i Arduino), alltså i starten - och då bara 1 gång.

Sedan väljer man vilken ingång som ska omvandlas, startar en omvandling och - utan interrupt - väntar till en omvandling är utförd.

När detta är gjort sparar man värdet från den ingång, väljer nästa ingång och gör samma sak (starta omvandling, vänta på att den är klar och spara värdet).

Nu är båda ingångar mätta och du kan välja vad som ska tändas.

Jag ser en logisk fälla i ditt urval: vad ska ske om BÅDA ingångar är under 2,5V?
I övrigt är 2,5V vid AD-värde 512.

Du släcker i övrigt hela port D för varje varv, om det är tillsiktad anser jag vara tveksamt. Den ska nollställas samtidig som A/D-omvandlaren initieras (och därmed bara 1 gång) och sedan bör den väl stå kvar som den är sedan senaste omvandling.
Tack för bra info!
Då har jag lite bättre koll på vart jag är ute och cyklar.

Om båda är under 2,5V i detta labprojekt tänkte jag att alla leds ska lysa. Alltså att bara varje ingång styr sina 4 leds.

I mitt "riktiga" projekt som är slutmålet skickas en 5V puls in i en xlr sladd. Två stift i kontakterna är byglade. Jag vill läsa av att spänning kommer fram i andra änden. I och med att stiften är byglade och "send kretsen" har indikator-leds så blir det spännings delning och 2,,5V som kommer fram till ADC pinnarna.

Mätte att min matning var 5.1V där av 500 som ADC värde. Dock inte exakt. Inte så noga i detta fallet.
Så det hade varit mer logiskt av mig att bara skriva 512 från början utan att mäta :)

Koden jag skrivit är ju C inte arduino!
När jag ser arduino koden nedan fattar jag inte varför jag inte kör det istället.
Verkar ju så mycket enklare men får samma sak gjort.
Men jag vill lära mig C ändå.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av Icecap »

OK.
I C kör ett program "alltid" såhär:

Kod: Markera allt

main:
  {
  // Gör alla initieringar osv, portar i rätt läge och vad vet jag.
  while(true) // Kör alltid!
    {
    // Här läser du A/D-grejerna och gör det du ska
    }
  }
Det går såklart att deklarera funktioner för att t.ex. initiera A/D-omvandlaren och liknande, jag har oftast en RTC_Init() om jag har monterat en RTC (realtidsklocka), en PWM_Init() om jag använder PWM, en Port_Init() typ alltid osv.

Det blir skitenkelt att läsa programmet: (pseudokod)

Kod: Markera allt

#define LED_Pins PORTD

void main(void)
  {
   uint16_t ADC4_Value;
   uint16_t ADC0_Value;
  Port_Init();
  AD_Init();
  while(true)
    {
    ADC0_Value = AD_Read(Pin0);
    ADC4_Value = AD_Read(Pin4);
    if(ADC0_Value >= 512) LED_Pins |= 0x0F;
    else LED_Pins $= ~0x0F;
    if(ADC4_Value >= 512) LED_Pins |= 0xF0;
    else LED_Pins $= ~0xF0;
    }
  }
Denna kod betyder såklart att du måste skriva uint16_t AD_Read(uint8_t Port_Select), void Port_Init(void) osv. men se hur enkelt det är att läsa programmet, det behöver knappast kommenteras.

Det enda lite speciella är LED_Pins |= 0x0F och LED_Pins $= ~0x0F;
Den första tar LED_Pins (alltså PORTD) och bitmässigt OR'er 0x0F in. De höga bits är orörda.
Det siste tar LED_Pins och bitmässigt AND'er 0xF0 in. '~' betyder "vänd varje bit i värdet" så ~0x0F == 0xF0.

Vid att definiera t.ex. LED_Pins kan man - på bara en plats - ange vilken port/portpin man vill använda och skulle man t.ex. flytta en pinne är det bara att ändra definitionen ett enda ställe och kompilera om och saken är biff.
tokfan
Inlägg: 694
Blev medlem: 10 juni 2010, 14:05:13

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av tokfan »

Skitbra inlägg icecap!
Allt känns lite rörigt för mig. Ditt inlägg gör att lite bitar faller på plats och gör allt mer strukturerat för mig.
Nu funkar ADC grejen. Tänkte använda det i programmet till min kabeltestare. Insåg då att jag formaterat och sålt datorn som det projektet låg på. :)
Börjar om och gör det ordentligt från början.

En till grej jag klurat på är när jag gör en header file med #define

Hur gör seriöst folk sådana?
Mina är typ:

#define ledport PORTB
#define redLed 0b00000001
#define buttonpin PINC
#define startButton 0b00000001

Brukar man skriva så eller på något tydligare vis?
I fallet ovan står ju redLed och startButton för samma sak. Känns slarvigt på något vis.
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av hawkan »

Använder du arduino är det ju bara att göra
varde=analogRead(pinne);
Krångla inte till det med en massa oväsentlig lågnivå.
tokfan
Inlägg: 694
Blev medlem: 10 juni 2010, 14:05:13

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av tokfan »

Fast jag kör inte arduino.
Har bestämt mig för att lära mig C-programmering.
Vet inte varför. Kul när det är klurigt och svårt kanske.
Användarvisningsbild
Klas-Kenny
Inlägg: 11292
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av Klas-Kenny »

Dina defines är det är inget konstigt med, inget fel alls att det finns flera med samma betydelse då de ska användas till olika saker (om du ändrar kortet så att någon annan pinne används till en viss funktion vill du bara behöva ändra i en define, inte gå igenom hela koden och ändra alla anrop).

Dock brukar man alltid använda enbart VERSALER_OCH_UNDERSTRÄCK i namnen på alla konstanter/defines. Underlättar vid läsning av kod att förstå att det är just det.
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av hawkan »

tokfan skrev:Fast jag kör inte arduino.
Har bestämt mig för att lära mig C-programmering.
Vet inte varför. Kul när det är klurigt och svårt kanske.
Det gör du ju i arduino. Pluset är att du slipper all lågnivå och kan
göra det du egentligen tänkt. Men kör du på.
Användarvisningsbild
Klas-Kenny
Inlägg: 11292
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av Klas-Kenny »

Med "ren" C får man dock lära sig mycket mer om hur man läser datablad och hur processorn egentligen fungerar. Vilket är mycket användbart vid många problem, och inte minst den dag man vill köra någon annan processor.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av Icecap »

I Arduino C är det helt rätt förtuggad mat man får. Det är enkelt och lätt - men samtidig förlorar man kontrollen över mycket.

I Arduino ska man FORTFARANDE initiera saker o ting - men de har gjort det en aning enklare med vissa saker.
Portar o pinnar ska ställas o data ska hämtas o lämnas. Vissa enklare saker blir nog enklare i Arduino medan andra är enklare i C.

Jag stödjer din strävan i att köra C, det är högre tröskel men sedan är det en standard man kan ta sig långt med.
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av hawkan »

Jag vet inte vad du menar med att nåt är enklare i C än i Arduino.

Arduino ÄR C!
tokfan
Inlägg: 694
Blev medlem: 10 juni 2010, 14:05:13

Re: AVR läsa av 2st ADC-pinnar typ samtidigt problem nybörja

Inlägg av tokfan »

Tack ska ni ha!
Ja min långsiktiga plan är att bli lite bredare.
Testade programmera arm men det blev för rörigt som nybörjare.
Det är nog mer nördandet än att få mycket gjort jag gillar. Med arduino skulle man ju få projekt ståendes i hela huset.
Börjar greppa lite av databladet nu. Blev tipsad om det i början men hade för dålig koll på allt så det var rena grekiskan.
Är fortfarande kass på språket men planen är att hitta på projekt och köra fast som nu och vara tvungen att lära mig för att komma vidare. Det känns lite som att en propp börjar släppa så jag i alla fall börjar förstå vad det är jag inte förstår. :)
Skriv svar