PIN read leest altijd nul

Op mijn Atmega328P heb ik op Pin PC1 een PIR sensor zitten.
Nu wil ik dus bij beweging een externe interrupt genereren.

De volgende interrupt routine laat inderdaad bij beweging het led op mijn board toggelen.

c code:


ISR (PCINT1_vect)
{
   led_toggle();
}

Echter deze routine triggerd ook op andere pinnen, dus zul je hem verder moeten uitpluizen welke pin er dan veranderd is.

Echter de volgende routine laat mijn led permanent uit.
Het lijkt erop dat hij PINC register niet kan uitlezen.

c code:


ISR (PCINT1_vect)
{
	if( (PINC & (1 << PINC1)) == 1 )
	{
		/* LOW to HIGH pin change */
		led_on();
	}
	else
	{
		/* HIGH to LOW pin change */
		led_off();
	}
}

Wat kan hier fout gaan?
Overigens op PC2 & PC3 bemonster ik ADC ingangen.
Kan dat nog van invloed zijn?

pax

Golden Member

Heb je de interrupt voor deze pin aangezet in het Pin Change Mask Register (PCMSK0)?

pax

Golden Member

Oh en natuurlijk de PCIE0 in het Pin Change Interrupt Control Register?
En de global interrupts?

Yes ik heb een global sei()

En mijn pir_init() is als volgt:

c code:


void pir_init(void) {
	PIR_PORT_DDR &= ~(1<<PIR_PIN_SIGNAL); //pir pin as input
	PIR_PORT &= ~(1<<PIR_PIN_SIGNAL); //disable pull-up
	//PIR_PORT |= (1<<PIR_PIN_SIGNAL); //enable pull-up
	
	PCICR |= (1 << PCIE1);    // set PCIE1 to enable PCMSK1 scan
	PCMSK1 |= (1 << PCINT9);  // set PCINT9 to trigger an interrupt on state change
	EICRA |= (1 << ISC10);
}

Het pir boardje heeft op de uitgang een pull down weerstand van 10k zitten.
Dus vandaar mijn disable pull-up.

EricP

mét CE

Zonder ook maar iets aan interfacing gelezen te hebben:

c code:

(PINC & (1 << PINC1)) == 1

gaat natuurlijk alleen maar werken op bit 0. Bij bit 1 zal de waarde na de and 0x02 zijn. Zijnde ongelijk 1...

Wat stom! Digitale techniek 101 :p
Dankjewel ik kan weer verder.

kijk eens bij de Arduino bitSet() en bitRead() macro's

EricP

mét CE

Ik ken het pin change interrupt mechanisme niet zo goed. Echter, wat je nu doet heeft nog een ander risico. Theoretisch kan je de ISR triggeren. Terwijl de AVR daarmee bezig is, kan je pin weer van state veranderen. Dan ga je dus de mist in.

Atmel heeft doorgaans best goed over dingen nagedacht, dus waarschijnlijk is er wel een foefje voor. Anders ontkom je haast niet aan een hardware oplossing.

Met een PIR zal het wel loslopen. Die is hoe dan ook vele malen trager dan een AVR - mits je de code een beetje redelijk schrijft.

Op 18 december 2018 17:09:03 schreef EricP:
Zonder ook maar iets aan interfacing gelezen te hebben:

c code:

(PINC & (1 << PINC1)) == 1

gaat natuurlijk alleen maar werken op bit 0. Bij bit 1 zal de waarde na de and 0x02 zijn. Zijnde ongelijk 1...

... Dus deze code kan je beter schrijven als:

code:


  ((PINC >> PINC1) & 1) == 1

Het alternatief is om != 0 te zetten ipv == 1, of je laat het helemaal weg.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Een tijdje terug was ik bezig met interrupts.
Nick Gammon legt dat heel mooi uit <https://gammon.com.au/interrupts>
Als de link eens goed doorbladert vindt je vast een oplossing.

Weer zo'n nodeloos ingewikkeld stukje C... ;)   In basic makkelijker te lezen.

pic basic code:


If PORTC.1_bit then ...

Ben net begonnen aan vertalen van code voor de W5500 chip. Heb het maar weer een tijdje weggelegd, want je wordt er nogal depri van... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com
EricP

mét CE

Wat is er ingewikkeld aan? Spruce schrijft het wat onhandig. Maar het geeft exact aan wat je doet - wat een heel groot voordeel is...

Er is overigens niks op tegen om een stapeltje macro's te maken zodat je jouw wel erg 'basic' schrijfwijze kunt hanteren. Het heeft waarschijnlijk wel een reden dat niemand dat doet :)

Op 18 december 2018 21:24:00 schreef Arco:
Weer zo'n nodeloos ingewikkeld stukje C... ;)   In basic makkelijker te lezen.

pic basic code:


If PORTC.1_bit then ...

Is niet ingewikkeld. Is gewoon logica. Als je een nette io abstractie laag er tussen legt, kun je op een laag hoger gewoon een bit in een structure vergelijken in een if statement

Op 18 december 2018 21:24:00 schreef Arco:
Ben net begonnen aan vertalen van code voor de W5500 chip. Heb het maar weer een tijdje weggelegd, want je wordt er nogal depri van... ;)

tsja, wat is er nu nadeloos ingewikkeld ;) (inkoppertje, sorry :))

Is niet ingewikkeld. Is gewoon logica. Als je een nette io abstractie laag er tussen legt, kun je op een laag hoger gewoon een bit in een structure vergelijken in een if statement

Dat kan een laag lager (assembler) ook met sbis en sbic en de meeste compilers accepteren wel een stukje assembler ertussen.

Ik moet toegeven dat het misschien een wat ingewikkeldere stijl is dan nodig, maar het gaat hier om een custom board dus dan vind ik het wel prettig om low level de pinnen aan te sturen.

Voor mijn gevoel ligt dat dichter op de schematics.
Persoonlijke voorkeur dus