Matrix met arduino

Heren

Als prille vijftiger en elektronica fanaat ben ik sinds kort gestart met arduino (beetje te lang blijven hangen bij "old skool" elektronica). Heb de online tutorials gevolgd van Paul Mcworther op youtube en daar heb ik heel veel van opgestoken (die kerel legt alles haarfijn uit). Echter nu heb ik een sketch van het internet gehaald om eens wat te experimenteren met Matrixen en van deze sketch snap ik het één en ander niet. In de "void setup" vermoed ik dat men iedere rij en iedere kolom van de matrix ( en dus in feite iedere LED) als uitgang definieert!? In de "void loop" veronderstel ik dat men het aantal keren definieert dat het programma de matrix scant (for (int i=0 ; i<200 ; i++))!? De "void Display" snap ik dan helemaal niet! Bij "void clear" worden waarschijnlijk alle rijen en kolommen "gewist"? Het werkt alvast perfect en voor wie het nog niet doorhad : er worden afwisselend een groot hart en een klein hart op de matrix gezet :-)!Is er iemand op het forum die degelijke verstaanbare antwoorden kan geven op mijn vragen? Alvast hartelijk bedankt voor de tijd en de moeite!!!!

c code:


int R[]{2,7,A5,5,13,A4,12,A2};
int C[]{6,11,10,3,A3,4,8,9};
unsigned char bigLove [8] [8]=
{
  0,0,0,0,0,0,0,0,
  0,1,1,0,0,1,1,0,
  1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,
  0,1,1,1,1,1,1,0,
  0,0,1,1,1,1,0,0,
  0,0,0,1,1,0,0,0, 
};
unsigned char smallLove [8] [8]=
{
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,1,0,0,1,0,0,
  0,1,1,1,1,1,1,0,
  0,1,1,1,1,1,1,0,
  0,0,1,1,1,1,0,0,
  0,0,0,1,1,0,0,0,
  0,0,0,0,0,0,0,0,
};
 

void setup() {
  for (int i=0 ; i<8 ; i++){
    pinMode (R[i] , OUTPUT);
    pinMode (C[i] , OUTPUT);
  }
}

void loop(){
  for (int i=0 ; i<200 ; i++){
   Display (bigLove);
  }
  for (int i=0 ; i<100 ; i++){
   Display (smallLove);
  }
}
void Display (unsigned char dat[8] [8]){
  for (int c=0 ; c<8 ; c++){
    digitalWrite (C[c] , LOW);
  for (int r=0 ;r<8 ; r++){
    digitalWrite (R[r] , dat[r] [c]);
 }
 delay (1);
 Clear ();
 }
}
void Clear(){
  for (int i=0 ; i<8 ; i++){
    digitalWrite (R[i] , LOW);
    digitalWrite (C[i] , HIGH);
  }
}

[Bericht gewijzigd door Henry S. op woensdag 9 oktober 2019 20:05:14 (0%)

setup(), loop() etc zijn allemaal functies. Functies (in C, de taal waarmee arduino's geprogrammeerd worden) zijn stukjes code die als bouwblokken fungeren: in je code (functies) kun je andere functies aanroepen, die na uitvoeren van hun stukje weer terugkomen op de oorspronkelijke plek.

Arduino programmas hebben altijd minimaal twee functies: setup() wordt een keer gestart na reset (en is dus een prima plek om IO pinnen te initialiseren). loop wordt (daarna) iedere keer opnieuw aangeroepen, de arduino library code doet ergens:

c code:


while(1) {
  loop()
}

Display() is een functie die door loop() gebruikt word, Clear een functie die door Display gebruikt word.

PinMode() en digitalWrite() zijn ook functies, die door de arduino library al gegeven zijn. En die mag je ook gewoon gebruiken.

void, tot slot, is wat de functie teruggeeft. In dit geval niets, een void.

Hoi blurp! Oeps :-(! Blijkbaar was mijn vraagstelling niet erg duidelijk :-(! Ik weet wat de functies doen en ook hoe de structuur werkt! Echter begrijp ik een paar stukken van de sketch niet (zie de zinnen waar ik "vermoed" en "waarschijnlijk" gebruik :-)).Als mijn veronderstellingen daar juist zijn hoef ik geen verdere uitleg alleen een bevestiging :-). Het stukje programma onder "void Display" snap ik helemaal niet :-(!U lijkt me er wel iets vanaf te weten dus kunt u het misschien ontrafelen? Toch al hartelijk bedankt voor uw antwoord!

Voordat we hier nou een hele Arduino-Wiki gaan neerpennen, die functies staan allemaal beschreven op de Arduino site:
https://www.arduino.cc/reference/en/#functions
Ik zou willen voorstellen om daar te beginnen met lezen, en dan horen wij de vragen wel weer :-)

[edit] ok, was voor mij ook onduidelijk dus. Maar ehm, wat is er onduidelijk aan die display() functie? Ik zie niet veel geks.

[Bericht gewijzigd door flipflop op woensdag 9 oktober 2019 20:16:16 (20%)

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

De matrix bestaat uit 8 rijen en 8 colommen met een led op elk kruispunt. Dus totaal 8 x 8 = 64 Leds.

De processor heeft één pin voor elke rij, en één pin voor elke kolom. Dus totaal 16 pinnen.

In Setup() zit een for loop. De variabele i loopt van 0 tot 8. Dus de loop wordt 8 keer uitgevoerd. Binnen de loop wordt i gebruikt als index in array C en array R. En in die array staan de pin nummers die gebruikt worden om de LED matrix aan te sturen.

De Display() funktie wordt vervolgens gebruikt om een plaatje naar de LED matrix te sturen. Die funktie wordt voor mij veel leesbaarder als je de haakjes op de goede plaats zet:

code:



void Display (unsigned char dat[8][8])
{
   for(int c = 0; c < 8; c++)
   {
      digitalWrite (C[c], LOW);

      for(int r = 0; r < 8; r++)
      {  digitalWrite (R[r], dat[r][c]);
         delay(1);
         Clear();
      }
   }
}

De buitenste for loop loopt de 8 colommen af. De gekozen kolom wordt aktief door de bijbehorende pin laag te maken.
Vervolgens loopt de binnenste for loop alle 8 rijen af. De pin wordt dan aangestuurd aan de hand van de 2-dimensionale array die via parameter dat wordt meegegeven aan de funktie. Dus dan gaat er 1 led aan (of niet) en blijft aan voor 1 milliseconde. Daarna wordt de hele matrix uitgeschakeld in de Clear() funktie (nogal inefficient eigenlijk) en dan is de volgende LED weer aan de beurt.

De Display(x) funktie scant dus de hele matrix één keer af. In loop() wordt de Display 200 keer achter elkaar aangeroepen, zodat de matrix 200 keer afgelopen wordt. Dan lijkt het net of er een stabiel beeld staat, terwijl er in werkelijkheid dus nooit meer dan één LED tegelijk aan staat.

--Edit
Oeps, foutje :

code:



void Display (unsigned char dat[8][8])
{
   for(int c = 0; c < 8; c++)
   {
      digitalWrite (C[c], LOW);

      for(int r = 0; r < 8; r++)
      {  digitalWrite (R[r], dat[r][c]);
      }
      delay(1);
      Clear();
   }
}

De binnenste loop schrijft hier alle 8 leds van de kolom die door de buitenste loop is gekozen. Dus er zijn tot max 8 leds tegelijk aktief.

@deKees: Je hebt bijna helemaal gelijk. Maar het helpt wel als je geen haakjes verschuift bij het netjes formatteren:

Op 9 oktober 2019 19:36:17 schreef Thunderace:

c code:


void Display (unsigned char dat[8] [8]){
  for (int c=0 ; c<8 ; c++)
  {
    digitalWrite (C[c] , LOW);
    for (int r=0 ;r<8 ; r++)
    {
       digitalWrite (R[r] , dat[r] [c]);
    }
    delay (1);
    Clear ();
  }
}

De delay() en Clear() zitten in de buitenste for-loop. Logisch, want in een matrix kun je alle leds in één kolom tegelijk aansturen.

@blurp.

Klopt, ik zag het ook. Dat is in de oorspronkelijke code moeilijk te zien. Dus dan zie je hoe belangrijk die indentatie is.

Voor mij is het volkomen onbegrijpelijk dat bijna iedereen dat 'verkeerd' doet :) .

benleentje

Golden Member

In de "void loop" veronderstel ik dat men het aantal keren definieert dat het programma de matrix scant (for (int i=0 ; i<200 ;

Deze regel zorgt er alleen maar voor dat de display functie 200x word uitgevoerd voor het symbool biglove.

De display functie werkt zoals DeKees het uitlegd. OF anders gezegt de display functie leest de biglove (of Smalllove) matrix in en zet de betreffende pinnen daarmee uit of aan.

Bij "void clear" worden waarschijnlijk alle rijen en kolommen "gewist"?

Nee er word niets gewist. IPV van data uit 1 van de matrix word er nu een vaste waarde naar de pinnen geschreven deze vaste waarden zorgen ervoor dat er geen enkel led brand. Als je in de functie clear de vaste waarden omdraait dan zullen alle leds aan zijn.

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

Op 9 oktober 2019 19:36:17 schreef Thunderace:
In de "void setup" vermoed ik dat men iedere rij en iedere kolom van de matrix ( en dus in feite iedere LED) als uitgang definieert!?

Klopt

In de "void loop" veronderstel ik dat men het aantal keren definieert dat het programma de matrix scant (for (int i=0 ; i<200 ; i++))!?

Ja, er wordt eerst 200 keer het ene, daarna 200 keer het andere hart getoond. Gezien er als bij een CRT scherm overheen "gescanned" wordt, moet dit op een hoge snelheid herhaald worden om de schijn van een volledig beeld te vormen. Er is hier echter sprake van scannen per lijn, niet per beeldpunt zoals bij CRT.

De "void Display" snap ik dan helemaal niet!

zie bijgevoegd commentaar

Bij "void clear" worden waarschijnlijk alle rijen en kolommen "gewist"?

Op een gedefineerde toestand gezet, zodanig dat vervolgens de rij en kolom pinnen alleen maar aangezet hoeven worden, het uitzetten is immers al in Clear() gedaan.

c code:


int R[]{2,7,A5,5,13,A4,12,A2};
int C[]{6,11,10,3,A3,4,8,9};
unsigned char bigLove [8] [8]=
{
  0,0,0,0,0,0,0,0,
  0,1,1,0,0,1,1,0,
  1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,
  1,1,1,1,1,1,1,1,
  0,1,1,1,1,1,1,0,
  0,0,1,1,1,1,0,0,
  0,0,0,1,1,0,0,0, 
};
unsigned char smallLove [8] [8]=
{
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,1,0,0,1,0,0,
  0,1,1,1,1,1,1,0,
  0,1,1,1,1,1,1,0,
  0,0,1,1,1,1,0,0,
  0,0,0,1,1,0,0,0,
  0,0,0,0,0,0,0,0,
};
 

void setup() {
  for (int i=0 ; i<8 ; i++){
    pinMode (R[i] , OUTPUT);
    pinMode (C[i] , OUTPUT);
  }
}

void loop(){
  for (int i=0 ; i<200 ; i++){
   Display (bigLove);                //roep Display aan met bigLove voor "dat"
  }
  for (int i=0 ; i<100 ; i++){
   Display (smallLove);              //roep Display aan met smallLove voor "dat"
  }
}
void Display (unsigned char dat[8] [8]){
  for (int c=0 ; c<8 ; c++){         //herhaal voor iedere kolom:
    digitalWrite (C[c] , LOW);       //1. zet de actieve kolom "aan"
  for (int r=0 ;r<8 ; r++){          //2. herhaal voor iedere rij:
    digitalWrite (R[r] , dat[r] [c]);//2.a. zet de rij naar de waarde zoals in "dat" beschreven
 }
 delay (1);                          //wachttijd waarin de actieve kolom wordt weergegeven
 Clear ();                           //doof scherm ter voorbereiding voor de volgende beeldlijn (kolom)
 }
}
void Clear(){
  for (int i=0 ; i<8 ; i++){
    digitalWrite (R[i] , LOW);
    digitalWrite (C[i] , HIGH);
  }
}
Meep! Meep!

Heren (roadrunner 84 , blurp , de kees en benleentje) hartelijk bedankt voor de klare uitleg en jullie tijd. Toppie! Het is me nu een stuk duidelijker! De hardware (de schakeling dus) maken op een breadboard is totaal geen probleem (ik knutsel al van in de Middeleeuwen met elektronica :-) ) en ik heb ook al heel veel opgestoken over functies en variabelen en de structuur van een sketch! Echter zoals ik reeds aangaf ben ik een “old skool” hobby elektronicus en “programmeren” is compleet nieuw voor mij! Ik amuseer mij echter als een varken in de modder met mijn nieuwe speeltje(s):-) ! Net zoals vroeger met transistoren en ic’s (vooral de 4000 serie) wil ik weten hoe de dingen werken! Ik kan klakkeloos de sketch van het internet in de arduino uploaden en het zal waarschijnlijk wel werken MAAR dat is voor mij niet bevredigend! Ik wil weten hoe de sketch inéén steekt! @ flipflop , ik begrijp uw opmerking ergens wel maar ik kan u verzekeren dat ik eerst zelf getracht heb om het te begrijpen voordat ik hulp zocht op het forum. Daar dient het voor dacht ik en niemand hoeft zich verplicht te voelen om een antwoord te geven (er zullen heus nog wel vragen volgen vrees ik :-) )!