ATmega324 Robot

Hallo,

formatting link
Ik heb ondertussen 2 drukknoppen aangesloten op PD2 en PD3 (dit zijn 2 interrupt ingangen) nu had ik graag in C deze ingangen als inte rrupt

programmeren om dit mogelijk te maken?

Reply to
sam decoster
Loading thread data ...

interrupt

moet programmeren om dit mogelijk te maken?

Als je de avr-gcc compiler gebruikt kun je op

formatting link

vinden hoe je een interrupt op een C-interrupt function aansluit. Voor het enablen van specifieke interrupts zul je in de datasheets moeten kijken.

Groetjes,

Rob

Reply to
Rob Windgassen

Bedankt Rob voor deze informatie, Ik ben zelf ook nog verder gegaan met zoeken naar informatie over interrupt

formatting link
g

Ik heb dan de code aangepast voor een ATmega324A:

#define F_CPU 16000000 #include #include #include

ISR(INT0_vect) { PORTB = 0x00; _delay_ms(100); }

int main(void) { DDRB = 0xFF; DDRD = 0x00; EICRA = (1

Reply to
sam decoster

Om dat dit meer over programmeren gaat dan elektronica heb ik follow-up gezet naar nl.comp.programmeren.

Voor microcontrollers met beperkt geheugengebruik zal je zelf de code zo moeten opzetten dat zoiets als multitasking kan. Een manier is om iedere 'taak' als state machine te implementeren die in een eigen coroutine wordt uitgevoerd. Je krijgt dan als main loop zoiets als

while (1) // main loop { do_task_A(); do_task_B(); // etc }

De coroutines zoals do_task_A() moet dan state handling doen voor taak A maar wel zonder meer tijd te consumeren dan de andere taken in de main tolereren voor hun reaktietijden. Zoiets als

void do_task_A(void) { static int state;

switch (state) { case OFF_STATE: if (... some condition is met ...) { ... set some output ... state = ON_STATE; } break;

case ON_STATE: if (... some other condition is met ...) { ... clear some output ... state = OFF_STATE; } break;

... add other cases when needed ... } }

Je zult dan wel je proces(sen) in state machine vorm moeten gieten (zoals in do_task_A hierboven) en dat kan, afhankelijk van wat je precies wil complex worden ... maar ja dat krijg je nu eenmaal met software ;-)

Groetjes,

Rob

Reply to
Rob Windgassen

Heel onhandig programmeren is dat helaas. Wat veel mensen niet weten is dat je in C ook een multitasker kunt schrijven waarin je meerdere taken kunt draaien die elkaar vrijwillig de controle overgeven. (dus zonder timeslices)

Het enige wat in een beperkte omgeving een probleem kan vormen is dat iedere taak zijn eigen stack heeft, en daar moet je dan wel RAM voor hebben. Dus op super simpele controllers met maar 64 bytes RAM aan boord lukt dit niet, maar als je niet teveel stack gebruikt (geen grote locale arrays) en een normale hoeveelheid RAM beschikbaar hebt dan kun je dit wel zo doen.

De truuk is het gebruik van setjmp/longjmp. Ik heb hier nog een .c file die voor het laatst in 1990 gewijzigd is waarin dit idee is uitgewerkt. Een geheel in C geschreven non-preemptive multitasker. Het enige wat je moet weten/uitzoeken is hoe de structuur van de jmp_buf voor je specifieke processor is en daaraan aanpassen van de #defines.

Reply to
Rob

oe

n

Het zou dus mogelijk zijn om op poortA een Knight Rider looplicht te zetten terwijl dat de robot andere instructies uitvoert zoals bv de snelheid vera nderen van de motor zonder dat het looplicht wordt onderbroken?

Reply to
sam decoster

Op maandag 30 december 2013 01:19:50 UTC+1 schreef sam decoster:

hoe

up

in

en terwijl dat de robot andere instructies uitvoert zoals bv de snelheid ve randeren van de motor zonder dat het looplicht wordt onderbroken?

elijk een ATmega8) zodat deze zorgt voor het looplicht terwijl de ATmega324 A alle andere zaken regelt, De ATmega8 krijgt dan een instructie van de ATm ega324A wat er moet verschijnen op de 8led's

Dit zou wel niet echt een logische oplossing zijn als het mogelijk is om te

eb.

Reply to
sam decoster
["Followup-To:" header set to nl.hobby.elektronica.]
  • Rob:

Het is maar wat je onhandig noemt.

Da's welbeschouwd niet heel veel anders dan de eerder genoemde loop, maar dan anders geimplementeerd, met meer overhead, terwijl OP een platformpje gebruikt met weinig geheugen. Slechte suggestie, IMHO.

Ik ben zeer benieuwd in die implementatie; de meeste "multithreading" implementaties op basis van setjmp/longjmp die ik heb gezien maken gebruik van ongedefinieerd gedrag.

Ah, platform-afhankelijk hackwerk dus. Dat is niet "C".

--
Martijn van Buul - pino@dohd.org
Reply to
Martijn van Buul

Het is platform-afhankelijk maar je hoeft geen assembly code te schrijven. Dat maakt het toch meer portable.

Ik hoef geen beoordeling van de oplossing, ik geef alleen een oplossing en als je er geen belangstelling voor hebt dan even goede vrienden. Zoals gezegd, het is 25 jaar geleden bedacht en heeft altijd goed gewerkt. Maar tegenwoordig gebruik ik dit niet meer omdat er op de platformen die ik gebruik altijd wel Linux draait en je dit soort oplossingen niet meer nodig hebt.

Reply to
Rob

Gebruik nooit interrupts voor drukknoppen (dat is een enorme beginnersfout *). Storingen, vocht en contactdender veroorzaken valse interrupts waardoor je controller trager wordt of zelfs helemaal vastloopt. De beste manier is de knoppen pollen vanuit een timer interrupt (b.v. 200Hz) en dan tellen hoeveel periodes de knop ingedrukt is (reset de teller indien niet ingedrukt). Na een X aantal periodes kun je vaststellen dat de knop echt ingedrukt is en dat het geen stoorpuls is. De methode met de teller is eenvoudig uit te breiden naar meten hoe lang een knop is ingedrukt.

  • Bronnen van interrupts moeten altijd voorspelbaar zijn. Dus maximaal een X aantal interrupts per tijdseenheid. Als je toch interrupts wil gebruiken voor knoppen dan moet je ervoor zorgen dat er een goed filter in de hardware zit (RC filter en Schmitt-trigger buffer).
--
Failure does not prove something is impossible, failure simply 
indicates you are not using the right tools... 
 Click to see the full signature
Reply to
Nico Coesel

Ik denk dat beide methodes hun voor en nadelen hebben. Met simpele threads zoals Protothreads:

formatting link
wordt het programmeren er niet overzichtelijker op. Het grote voordeel van een scheduler zoals jouw naamgenoot voorsteld is dat iedere 'taak' de hele stack tot zijn beschikking heeft en dat de flow van het programma te volgen blijft zonder dat er allerlei dingen verborgen onder de motorkap gebeuren.

--
Failure does not prove something is impossible, failure simply 
indicates you are not using the right tools... 
 Click to see the full signature
Reply to
Nico Coesel

Dat schrijft hij toch ook: "taken als state-machine implementeren" en daar is niets mis mee. Het kost wat meer code maar je hebt per taak minimaal

--
Wil
Reply to
Wil Taphoorn

Sam (OP) moet maar kijken wat voor hem het handigste werkt. Als ie er tijd voor heeft en wil experimenteren dan is het aan te raden om verschillende varianten uit te proberen en dan te zien wat daar de voor- en nadelen zijn.

Groetjes,

Rob

Reply to
Rob Windgassen

Het vergt over het algemeen veel meer design effort. Op zich niet slecht om aandacht te besteden aan design ipv direct te gaan coden, maar je kunt de aandacht beter aan nuttige zaken besteden dan aan het uitdokteren van een schema van state transities.

Reply to
Rob

Hoe handig het toepassen van state machines is hangt sterk af van het probleem wat opgelost dient te worden.

De klasse van problemen waar (gesamplede) inputs een systeem besturen is i.h.a. juist goed aan te pakken m.b.v. state machines. Het opstellen van de state machine 'dwingt' de ontwerper om voor iedere state voor alle mogelijke inputs over de juiste afhandeling na te denken. Als de ontwerper dit onder de knie heeft resulteert dit in zeer robuuste oplossingen.

Groetjes,

Rob

Reply to
Rob Windgassen

Bedankt iedereen voor deze nuttige informatie. Ik zal eens bekijken wat voor mij de beste oplossing is.

Groeten Sam Decoster

Reply to
sam decoster

prima toch ik zag in de rest dat je daar ondertussen uit was, ik heb wel bezwaar tegen die delay want die zorgt er nu precies voor dat het te langzaam gaat. je moet zorgen dat je loop (main) zo snel mogelijk doorlopen wordt. interupt werkt prima maar als je daar een delay inzet dan gaat het niet snel. je kunt een wachtlus maken met (in arduino) milli()

newtime=milli() if newtime -oldtime > waittime then oldtime:=newtime doen wat je wilt zoals de looplicht 1 verder zetten endif

met de drukknoppen (die je ook gewoon in de loop kunt zetten nu) moet je door contactdender wel even opletten dat je zodra een drukknop gedecteerd word deze even op hold zet want anders zie je de knop meermalen doorkomen, de loop heeft maar 1 mills of minder nodig om helemaal te loopen. dat doe ik dus ook met zo een tijdconstructie als hierboven. er is een goede nederlandse forum op arduino en een nog veel grotere op arduino.cc. groetjes snipped-for-privacy@home.nl

Reply to
polleke

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.