[C] Led patronen kiezen met while-loops

Status
Niet open voor verdere reacties.

UneXisted

Gebruiker
Lid geworden
16 sep 2008
Berichten
20
Ik wil graag een c-code schrijven zodat ik met een druk op de knop een led patroon kan wijzigen.

Dus stel ik heb een code die zegt dat bij het drukken van de knop de variabele i verhoogd word. Dan krijg je vervolgens de while-loops.

Code:
if( button_is_pressed)
{ i++}

while( i == 0 ) {
led patroon 1
}
while( i == 1 ) {
led patroon 2}
if( i == 2 )
{ i = 0; }

Nu is het probleem dat als i = 0 en ik verhoog hem met 1, dan blijft hij hangen in de while-loop. Want hij checkt pas de voorwaarden als hij zijn loop heeft afgemaakt, hoe kan ik ervoor zorgen dat hij automatisch naar de volgende while loop gaat?
 
Laatst bewerkt:
waarschijnlijk ergens i++ toevoegen?

tenminste dat lijkt mij het meest logisch
 
Dit gaat over microControllers neem ik aan? (leds, knoppen)

Als je de code zoals hij hiewrboven staat wilt gebruiken, zul je de knop wel op een interrupt aan moeten sluiten anders zal hij of blijven hangen in de while-loop of er nooit inspringen :)
 
Dit gaat over microControllers neem ik aan? (leds, knoppen)

Als je de code zoals hij hiewrboven staat wilt gebruiken, zul je de knop wel op een interrupt aan moeten sluiten anders zal hij of blijven hangen in de while-loop of er nooit inspringen :)
Daar ben ik me bewust van ja. Maar dit is niet een forum voor microcontrollers, dus als ik die code erbij zet dan snappen veel mensen het denk ik niet.

Maar daar gaat het me ook niet om, de vraag die ik stel kan je ook met deze kennis beantwoorden. Het punt is namelijk dat ik in een interrupt ofzo geen break kan zetten, want dan beeindig ik niet de while-loop. In de interrupt verander ik de voorwaarde van een while-loop, maar hij checkt pas na de iteratie of die nog voldoet. Ik zou eigenlijk willen dat die gelijk optreed naar de verandering van de variabele i.
 
Embedded software is mijn vakgebied. Dus ik was waarschijnlijk niet geschrokken van je code :)

Maar je hebt inderdaad gelijk: Pas als het complete statement-block doorlopen is, zal de waarde van I opnieuw gecontroleerd worden.
Ik weet niet wat je in 'led_patroon' functie doet? Misschien dat je daar ook naar 'i' kunt kijken om er zodoende uit te springen.
 
Embedded software is mijn vakgebied. Dus ik was waarschijnlijk niet geschrokken van je code :)

Maar je hebt inderdaad gelijk: Pas als het complete statement-block doorlopen is, zal de waarde van I opnieuw gecontroleerd worden.
Ik weet niet wat je in 'led_patroon' functie doet? Misschien dat je daar ook naar 'i' kunt kijken om er zodoende uit te springen.

Bedoel je in de while loop een if( i == x ) { break; }

Zoiets? Slaat die break; dan niet op de iteratie van if? Of gebruik ik het woord iteratie verkeerd? :p

Ik zal vanavond de code posten, het gaat om een ledkubus. :)
 
Slaat die break; dan niet op de iteratie van if? Of gebruik ik het woord iteratie verkeerd? :p

Wikipedia:
De definitie van het woord iteratie is herhaling. Het is een begrip uit de wiskunde en informatica, bedoeld om aan te geven dat met een bepaald zich herhalend proces een berekening kan worden uitgevoerd. In computertermen zou dit een "loop" worden genoemd.
Een if itereert niet, met break zal hij dus uit de while loop springen :)
 
Volgens mij schort er wat aan de logica van je code.

Als ik het geod begrijp heb je ergens een signaal (interrupt) dat, wanneer dat gegeven wordt (is_button_pressed == true) van led-patroon moet veranderen.

Als je met patroon een sequentie bedoeld (bvb knipperen/looplichttoestanden), zou ik je verschillende patronen als array's/vectoren bewaren. En deze dan nog eens in 1 overkoepelende vector plaatsen.

Dan werk je ergens met een kloksignaal/timer, en elke puls/tick voer je een code uit die:
  1. kijkt of je button ingedrukt werd en als dat zo is, dan verandert de patroon-index en wordt de stepindex op 0 geset
  2. het patroon op [patroonindex][stepindex] wordt naar je led(s) verzonden
  3. de stepindex wordt verhoogd
  4. indien de stepindex gelijk is aan de lengte van de vector op patroonindex, wordt stepindex op nul geset

Wanneer je programma beëindigd moet worden, is er een interrupt (power-signaal bvb) welke de timer stopt.
 
Een voorbeeld code is hieronder gegeven. Het gaat om de ATmega32 op 8MHz.

Code:
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>

volatile int status = 0;

void col_out()  // all columns low = all leds off
{
  PORTA = 0x00;
  PORTB = 0x00;
  PORTC = 0x00;
  PORTD = 0x00;
}

void test()  // all leds on with a frequency of 100Hz
{
  col_out();
  for( int i = 0; i < 100; i++)  // 1 second
  {
  if( status == 1 )
  break;
  PORTA = 0xFF;
  PORTC = 0xFF;
  PORTD = 0xFB;
  PORTB = 0xD0;  // layer 5 on
  _delay_ms(2);
  PORTB = 0xE8;  // layer 4 on
  _delay_ms(2);
  PORTB = 0xE4;  // layer 3 on
  _delay_ms(2);
  PORTB = 0xE2;  // layer 2 on
  _delay_ms(2);  
  PORTB = 0xE1;  // layer 1 on
  _delay_ms(2);
  }
}



ISR(INT0_vect) // if a button is pressed
{
status++;           
if(status >= 2)
  status = 0;

}

int main(void) {

DDRA = 0xFF;
DDRB = 0xFF;
DDRC = 0xFF;
DDRD = 0xFB;

GICR = 0x40;
MCUCR |= (1<<ISC01) | (0<<ISC00); // on falling edge
sei();


while(1) {


    while( status == 0 )
    test();

	while( status == 1 )
	col_out();
   	
}
}

Edit: hij doet het nu geloof ik, alleen.. moet ik nu dus in elke for-loop een if() {break;} statement zetten? Zijn er geen efficiëntere oplossingen?
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan