2x interrupt werkt niet

trix

Golden Member

atmega 16

hallo,
ik ben bezig om een gemoduleerd signaal te maken voor een IR led.
volgens mij heb ik het al eens werkend gehad, maar het lukt nu niet.

ik wil met 2 timers (0&1) een compare match interrupt maken.
ik heb de code terug gebracht tot het meest essentieele voor dit probleem.
dus in 2 verschillende interrupts worden 2 led's ge-toggeld rood en groen.
beide leds werken wel los van elkaar (ik // dan de andere weg)
maar beide tegelijk werkt niet, dan werkt alleen de gele led ????

ziet iemand wat er fout gaat ?

c code:


#define F_CPU 8000000UL // 8 MHz clock speed

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

	ISR(TIMER0_COMP_vect) 
	{
		PORTD = PORTD ^(1 << PIND7); // togle led rood^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^	
	}

	ISR(TIMER1_COMPA_vect) 
	{
		PORTD = PORTD ^(1 << PIND5); // togle led geel^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	}

int main(void)
{
	PORTD |= (1 << PIND4);
	PORTD |= (1 << PIND5);
	PORTD |= (1 << PIND7);
	
	
	DDRD = 0b11111111;
	
	sei(); // global interrup enable
	
	TCCR0 |= (1 << WGM01) | (1 << CS00); // CTC-mode, no prescaling
	TIMSK |= (1 << OCIE0); // timer 0 compare match interrupt enable
	OCR0 = 105;
				
	TCCR1B |= (1 << WGM12); // CTC-mode,
	TCCR1B |= (1 << CS12) | (1 << CS10); // start timer with prescaler = 1024^^^^^^^^^^^^^^^^^^^^^^
	TIMSK = (1 << OCIE1A); // timer1 A compare match interrupt enabled
	OCR1A = 2500;
				
	for(;;)
	{
		
	}
}
eigenwijs = ook wijs

code:


TIMSK = (1 << OCIE1A); // timer1 A compare match interrupt enabled

Uitroepteken ontbreekt. Nu zet je OCIE0 weer uit.

trix

Golden Member

getest en werkt,
wat kan je toch soms langs de meest simpele dingen heen kijken 8)7
bedankt.

eigenwijs = ook wijs
trix

Golden Member

nu ik toch (alweer) aan het vragen ben:

wat is de eenvoudigste (beste) manier om een pulstrein van 38kHz te maken ?
ik ben nu aan het proberen om dat met een variabele te doen genaamd: khz_train.
later wil ik die dan "ennen" met een output pin (24 x),
mijn grootste probleem op dit moment is om een variabele te maken die met 38kHz aan/uit gaat.

hieronder een stukje v/d code waar ik dat : "ennen" met de output wil doen

c code:


if (pulse_train == 1)	{PORTB = (khz_train & 1);}
if (pulse_train == 2)	{PORTB = (khz_train & 2);}
if (pulse_train == 3)	{PORTB = (khz_train & 4);}
if (pulse_train == 4)	{PORTB = (khz_train & 8);}
if (pulse_train == 5)	{PORTB = (khz_train & 16);}
if (pulse_train == 6)	{PORTB = (khz_train & 32);}
if (pulse_train == 7)	{PORTB = (khz_train & 64);}
if (pulse_train == 8)	{PORTB = (khz_train & 128);
eigenwijs = ook wijs

Ik gebruik een pwm poort van 38kHz en moduleer dat met de UART.
Gezien de UART poort in rust hoog is wordt er enkel maar IR uitgezonden als er data op de UART poort verschijnt.

Zie bijgevoegd schema, misschien is dat een beter idee dan te werken met interrupts.

LDmicro user.
Arco

Special Member

Meeste nieuwere pic's hebben daarvoor een DSM module (Data Signal Modulator), heel erg handig. Maar alles met 1 timer(interrupt ) moet ook prima gaan...

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

Golden Member

de uart poort heb ik al in gebruik (Rs485)

eigenwijs = ook wijs

Als je zelf een data poort maakt aan de zenderzijde, zul je ook aan de ontvangstzijde dezelfde timing moeten hanteren.
Ik dacht dat je een software uart kon maken op gelijk welke pin?

LDmicro user.
trix

Golden Member

met mijn methode moet het toch ook redelijk eenvoudig kunnen, ik hoef alleen een variabele met 38 kHz aan en uit te doen.

maar als ik in de interrupt een variabele set khz_train = 1; en ik doe in de main if (khz_train == 1) {PORTD |= (1 << PIND7);} dan werkt dat niet.
hangt me iets bij van volatile, ge ik eens proberen.

eigenwijs = ook wijs

Als je de data aan de ontvangstzijde niet kunt synchroniseren met de zendersnelheid zal dat niet werken, je zult dan ook een clocksignaal moeten meesturen, dat is de sterkte van de uart, door de baudrate staat alles op voorhand vast.

LDmicro user.
trix

Golden Member

ik begrijp even niet goed waar je het nu over hebt, ik vermoed dat je met de ontvangstzijde de IR ontvangers bedoeld. dat komt later waneer ik een gemoduleerd signaal op IR led's heb staan, maar daar gebruik ik al uart voor over een RS485 bus.

eigenwijs = ook wijs

Ik begrijp enkel dat je via IR een pulstrein met data wilt verzenden maar als dat niet zo is mag je mijn posts negeren, dan heb ik het verkeerd begrepen.

[Bericht gewijzigd door MGP op donderdag 26 maart 2020 13:59:58 (13%)

LDmicro user.
trix

Golden Member

wat ik op dit moment wil is eigenlijk heel simpel:

- 24 leds die 1 voor 1 aan gaan (als een looplicht)
- ze zijn nu voor c.a. 500 mS hoog (word later 4 mS)
- de tijd dat ze hoog zijn moet worden op gedeeld in een freq van 38 kHz (26 uS)

eigenwijs = ook wijs
Arco

Special Member

Wat is dat signaal? Wordt dat verstuurd via een IR diode naar 24 ontvangers?

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

Golden Member

dat word verstuurd van 1 IR diode naar 1 IR ontvanger

eigenwijs = ook wijs
trix

Golden Member

IR diode........IR ontvanger

1---------------> 1
2---------------> 2
3---------------> 3
4---------------> 4
.
.
.
.
.
.
.
23-------------> 23
24-------------> 24

eigenwijs = ook wijs
Arco

Special Member

Als een led aan moet, stuur je een 500mS burst. Maar wat stuur je als de led uit moet?

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

Golden Member

gewoon een "0"
mijn plaatje is een beetje vertekend (en daarmee mischien verwarrend)
de "laag tijd" tussen de burst-en is veel korter dan getekend, zoals getekend zit er een "dode" tijd tussen de led's. maar dat is niet zo, ze gaan na genoeg zonder "dode tijd" na elkaar.

ik heb ook maar 4 pulsen in 1 burst getekend, maar dat zijn er natuurlijk ruim 19000. (500mS / 26uS)

[Bericht gewijzigd door trix op donderdag 26 maart 2020 15:18:09 (16%)

eigenwijs = ook wijs
Arco

Special Member

Je zult toch iets van synchronisatie moeten hebben, bijv. een 'leader' burst...
(als je gewoon niks stuurt bij led uit, wat doe je dan als led 1 uit moet?)

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

Golden Member

o....op die manier, had ik zo snel niet begrepen,...mijn fout.

ik ben een beetje bang dat we nu ver af gaan wijken van de oorspronkelijke vraag, maar ik hoop dat iemand weet hoe dit het best te doen.

maar om je vraag te beantwoorden.
de zender (24x IR led) en de ontvanger (24x IR ontvanger) hebben ieder een atmega 16. deze verzorgen:
- bij de zender zijde het looplicht.
- bij de ontvanger zijde dat de ontvanger behorende bij de IR led die is aangestuurd actief is.
- bij de ontvanger de ontvangen data word op gelagen
- bij de ontvanger dat de opgeslagen data word verstuurd naar de master (atmega 2560) (met uart over RS485). word appart om gevraagd vanuit de master.

dus ik stuur vanuit de master gelijk tijdig een start signaal naar de zend en de ontvangst zijde. vervolgens verzorgen die zelf het "looplicht".
omdat alles op een externe x-tal draait blijft de zender & ontvanger mooi synchroon. tenminste dat hoop ik :)

eigenwijs = ook wijs

Ik begrijp nog niet wat je wilt maar dat terzijde, welke IR ontvanger gebruik je?

LDmicro user.
trix

Golden Member

tsop ..38
weet niet exact welke uit mijn hoofd.
je kan in de zoekfunctie met mijn naam zoeken, het meeste wat je vind gaat over dit project.

eigenwijs = ook wijs

Een TSOP4838 ... en daarom vermoed ik dat je niet goed bezig bent.

Op 26 maart 2020 12:15:43 schreef trix:

mijn grootste probleem op dit moment is om een variabele te maken die met 38kHz aan/uit gaat.

hieronder een stukje v/d code waar ik dat : "ennen" met de output wil doen

c code:


if (pulse_train == 1)	{PORTB = (khz_train & 1);}
if (pulse_train == 2)	{PORTB = (khz_train & 2);}
if (pulse_train == 3)	{PORTB = (khz_train & 4);}
if (pulse_train == 4)	{PORTB = (khz_train & 8);}
if (pulse_train == 5)	{PORTB = (khz_train & 16);}
if (pulse_train == 6)	{PORTB = (khz_train & 32);}
if (pulse_train == 7)	{PORTB = (khz_train & 64);}
if (pulse_train == 8)	{PORTB = (khz_train & 128);

Ik "zie" nog altijd niet wat je wilt doen, een variabele maken die met 38kHz aan of uit gaat zegt mij niks.
Werken met een TSOP is volgens mij nog altijd een "timing" aangelegenheid, tenzij je een latch schakeling maakt, IR signaal = aan en nogmaals een IR signaal = af.

LDmicro user.

Op 26 maart 2020 10:18:46 schreef trix:

c code:


	ISR(TIMER0_COMP_vect) 
	{
		PORTD = PORTD ^(1 << PIND7); 
	}

Dit kan om een paar instructies in de interrupt te sparen iets efficienter met:

code:


		PIND = 1 << PIND7; 

Wat het oplevert valt me tegen. De IRQ routine gaat van 15 instructies naar 14 instructies. Het scheelt 33% op het stuk wat het werk doet (van 3 naar 2 instructies), maar wat er omheen zit maakt dat het niet veel doet.

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

Golden Member

reactie is meer voor MGP bedoeld, er kruiste nog een andere post.

die variabele is de: khz_train
die kan ik dan met een masker op de uitgangs poort leggen (8 bits)
precies zoals in het door jou ge-quote stukje. wat overigens nog niet is getest, omdat ik daar die khz_train op 38 kHz moet kunnen laten toggelen.
stel je voor dat dat lukt, dan zie je in dat ge-quote stukje toch een looplicht die voldoet aan het eerder door mij geposte plaatje.

maar ik had net een ingeving, die ik morgen ga testen, ik laat nog wel weten of het gelukt is.

eigenwijs = ook wijs