[Arduino] Klokje met shift-registers in Simulide

Pagina: 1
Acties:

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
Een snellere en makkelijkere methode om een hex-file in Simulide te krijgen, die staat hier :

https://www.botshop.co.za/2017/02/

In het kort, klik in Arduino software op Sketch, klik op Export compiled Binary.
In die link staat ook een video maar vond dat eerder verwarrend als verduidelijkend.

Er zijn een paar typen Arduino micro-controller units (Mcu), de Uno is het meest gebruikt.

Zet er een programma in, ook wel sketch of code genoemd en de leds komen in beweging.

Afbeeldingslocatie: https://i.imgur.com/UIo38UT.jpg?1
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//  Om de 2 seconden gaat een led branden, er zijn 3 seconden leds
//  Elke led moet 20 seconden voorstellen
int S00 = 10;      // De drie seconden leds
int S20 = 11;
int S40 = 12;

void setup() {                
  // initialize the digital pin as an output.
  pinMode(S00, OUTPUT);   
  pinMode(S20, OUTPUT);  
  pinMode(S40, OUTPUT);    
}
void loop() {
delay(2000);                     // wait for 2 secondS
digitalWrite(S00, HIGH);    // turn the LED on (HIGH is the voltage level)
delay(2000);                     // wait for 2 secondS
digitalWrite(S20, HIGH);    // turn the LED on (HIGH is the voltage level)
delay(2000);                     // wait for 2 secondS
digitalWrite(S40, HIGH);     // turn the LED on (HIGH is the voltage level)
delay(2000);                      // wait for 2 secondS
digitalWrite(S00, LOW);      // turn the LED off by making the voltage LOW
digitalWrite(S20, LOW);      // turn the LED off by making the voltage LOW
digitalWrite(S40, LOW);      // turn the LED off by making the voltage LOW
}

[ Voor 5% gewijzigd door kitao op 17-03-2019 21:46 . Reden: In het kort ]


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
Room42 schreef op zaterdag 16 maart 2019 @ 00:53:
@kitao Wil je even een TeamViewer starten en je ID hier posten, dan kan ik even in jouw lokale Temp-folder kijken. ;)
Ik weet echt totaal niet waar je het over hebt, en dat is geen grap, TV en TF zeggen mij niets. Heb wel je edit gelezen, de opzet is aan het einde van dit voorbereide topic, na slechts 5 postjes, wel duidelijk hoop ik.

Ps\
Bedankt voor de tip, heb een intro toegevoegd :)

********

Zonder code in de micro gebeurt er niks en dat is meteen het nadeel, wie zelf geen code kan schrijven zal voorbeelden moeten gebruiken.
Daar zijn er wel veel van, zoals op deze website :

https://www.arduino.cc/en/Tutorial/BuiltInExamples

Na verloop van tijd wordt dan vanzelf de basis van programmeren duidelijk of je begint aan een paar lessen daarover, zoals deze bijvoorbeeld :

https://arduino-lessen.nl/

Zelf programmeren heeft wel voordeel, zo kan je je eigen ontwerp maken dat niet in een voorbeeld staat. Programmeren is zoiets als wiskunde, er komt vrijwel geen einde aan en het wordt steeds complexer maar met de basis valt al genoeg mee te maken, zoals een klokje die stap voor stap is opgebouwd.

Afbeeldingslocatie: https://i.imgur.com/1hmWpyx.jpg?1

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Er zijn 3 seconden leds, 3 minuten leds en 3 uren leds
// Elke led moet een bereik van 15 seconden, 15 minuten of 3 uren voorstellen
// Drie leds op een rijtje in de uitstand betekent dat de 'wijzer' tussen de 60 en 15 staat.
// De blinde vlek in deze 'klok' is dus 3 uur.

int t = 1000; // Verander hiermee de Delays in één keer.

int S15 = 4;  int S30 = 5;  int S45 = 6;       // De seconden leds
int M15 = 7;  int M30 = 8;  int M45 = 9;       // De minuten leds
int U15 = 10; int U30 = 11; int U45 = 12;      // De uren leds

void setup() {   // initialize the digital pins as an output.      
  pinMode(S15, OUTPUT) ; pinMode(S30, OUTPUT); pinMode(S45, OUTPUT); 
  pinMode(M15, OUTPUT) ; pinMode(M30, OUTPUT); pinMode(M45, OUTPUT);  
  pinMode(U15, OUTPUT) ; pinMode(U30, OUTPUT); pinMode(U45, OUTPUT);      
}

void loop() {
      for (int u = 1; u < 5; u++) {     // lus voor UREN
        if (u == 1){
          digitalWrite(U15, LOW);       // alle leds uit 
          digitalWrite(U30, LOW);       // positie 1
          digitalWrite(U45, LOW);       // bereik 60-15 
          delay(t);          }           // wait for t seconds
              if (u == 2){
          digitalWrite(U15, HIGH);      // zet led U15 aan, bereik 15-30
          delay(t); }                     // wait for t seconds
              if (u == 3){
          digitalWrite(U30, HIGH);      // zet led U30 aan, bereik 30-45 
          delay(t);  }                   // wait for t seconds
                  if (u == 4){
          digitalWrite(U45, HIGH);      // zet led U45 aan, bereik 45-60 
          delay(t); }                    // wait for t seconds
          
      for (int m = 1; m < 5; m++) {  // geneste lus voor MINUTEN
        if (m == 1){
          digitalWrite(M15, LOW);       // alle leds uit 
          digitalWrite(M30, LOW);       // positie 1
          digitalWrite(M45, LOW);       // bereik 60-15 
          delay(t);          }           // wait for t seconds
              if (m == 2){
          digitalWrite(M15, HIGH);      // zet led M15 aan, bereik 15-30
          delay(t); }                     // wait for t seconds
              if (m == 3){
          digitalWrite(M30, HIGH);      // zet led M30 aan, bereik 30-45 
          delay(t);  }                   // wait for t seconds
                  if (m == 4){
          digitalWrite(M45, HIGH);      // zet led M45 aan, bereik 45-60 
          delay(t); }                    // wait for t seconds
          
      for (int s = 1; s < 5; s++) {  // geneste lus voor SECONDEN
        if (s == 1){
          digitalWrite(S15, LOW);       // alle leds uit 
          digitalWrite(S30, LOW);       // positie 1
          digitalWrite(S45, LOW);       // bereik 60-15 
          delay(t);          }           // wait for t seconds
              if (s == 2){
          digitalWrite(S15, HIGH);      // zet led S15 aan, bereik 15-30
          delay(t); }                     // wait for t seconds
              if (s == 3){
          digitalWrite(S30, HIGH);      // zet led S30 aan, bereik 30-45 
          delay(t);  }                   // wait for t seconds
                  if (s == 4){
          digitalWrite(S45, HIGH);      // zet led S45 aan, bereik 45-60 
          delay(t); } } } }               // wait for t seconds
}

[ Voor 1% gewijzigd door kitao op 16-03-2019 20:24 . Reden: Ps\ ]


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
Er zijn nu al 9 leds en daar zijn 9 pinnen voor nodig en de Uno heeft ca. 18 pinnen die als output gebruikt kunnen worden dus die zijn snel op.
Om grotere aantallen leds te gebruiken worden er daarom IC's, integrated circuits oftwel chips, toegevoegd.
In deze opstelling heb ik voor de 74HC595 gekozen, waarvan hier meer toelichtingen :

https://www.arduino.cc/re...ons/advanced-io/shiftout/
https://www.arduino.cc/en/Tutorial/ShiftOut
http://artimesdiy.nl/inde...catid=46:lessen&Itemid=76

Afbeeldingslocatie: https://i.imgur.com/jMpBo2a.jpg
klik voor groter, je komt dan in imgur, klik er nog een keer op

Led M00 die toch al constant Laag werd gehouden afgekoppeld om er een Latch van te maken want alle pinnen zijn nu vol aan de beneden zijde van de Uno.
Pin 12 is Data en 13 de Clock.
Chip 2 nog niets aan gedaan behalve de ledjes erop gezet, die moet vanaf 9 t/m 12 gaan tellen.
Wou er ook nog een mogelijkheid inzetten om tenminste de uren van tevoren te kunnen instellen zodat er niet tot middernacht gewacht hoeft te worden om de klok gelijk te krijgen. Niet dat de Simulide het zo lang volhoudt, dan is die al lang en breed vastgelopen, meestal houdt die het slechts 5 minuten vol.

Hier een afbeelding hoe chip1 zit aangesloten, chip2 doet nog niks

Afbeeldingslocatie: https://i.imgur.com/ETnkytv.jpg
klik voor groter

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 0011 =  3 = 2^2 - 1
// 0111 =  7 = 2^3 - 1
// 1111 = 15 = 2^4 - 1  etc.
// Met deze benadering valt er een lus te maken.
// pow bleek nodig te zijn om machts te verheffen (in shiftout regel 22) 
// Uren-led U00 blijft net als bij de minuten-led M00 buiten beeld.

int latchpin = 6;     // Pin aangesloten op ST_CP van 74HC595
int clockpin = 13;   //  Pin aangesloten op SH_CP van 74HC595
int datapin = 12;   //   Pin aangesloten op DS    van 74HC595
int t = 1000;      //    Verander hier de snelheid in milli-seconden

void setup() {
  pinMode(latchpin, OUTPUT);    // Zet de pinnen op Output
  pinMode(clockpin, OUTPUT);
  pinMode(datapin,  OUTPUT);
}
void loop() {
  for (int i = 2 ; i < 9 ; i++) { 
    
    digitalWrite(latchpin, LOW);  // Latchpin laag
    shiftOut  (  datapin, clockpin, LSBFIRST,  pow ( 2 , i ) - 1  );
    digitalWrite(latchpin, HIGH); // Latchpin Hoog
    
    delay(t);   }   // delay + einde for-lus
    
    digitalWrite(latchpin, LOW);  // Latchpin laag
    shiftOut  (  datapin, clockpin, LSBFIRST, 0  );  // Alle leds uit
    digitalWrite(latchpin, HIGH); // Latchpin Hoog
    
    delay(t);  
    
}  // return naar void loop

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
- Voor opbouw deze websites geraadpleegd :
https://www.arduino.cc/en/Tutorial/ShiftOut
http://artimesdiy.nl/inde...catid=46:lessen&Itemid=76
- Datasheet : http://www.ti.com/lit/ds/symlink/sn74hc595.pdf

- Dit schema zit in een virtuele omgeving en om de leds wat feller op de monitor te krijgen, 120 Ohm weerstanden toegepast. In het echt is toch wel minstens 220 Ohm aan te raden, of zoals in de Tutorial 470 Ohm. Daar staat ook iets over een condensator.
- De twee 5 Volt schakelaars onderin betekent niet dat er in het echt extra voeding nodig is.
- De codes in de Tutorial kunnen gebruikt worden als de nummers voor de pinnen latch, data, clock, worden gewijzigd.

[Pow]
Het gebruik daarvan gaf onverwachte gevolgen want er bleek dat bijvoorbeeld 2 kwadraat geen 4 oplevert maar 3.9999 omdat het een float/double is. Vertaald naar een int krijg je dan als resultaat 3 ipv 4. Dit had als bijkomstig gevolg dat ik Q7 van chip2 heb overgeslagen.
In de eerste schakeling heb ik een extra latch-pin erbij gezet, A5. Door deze een puls te geven wordt de data ingelezen op chip2. Op die manier krijgt iedere chip zn eigen data. Led U00 is draadje doorgeknipt, die wou ik namelijk uit laten en kwam toevallig ook beter uit bij het programmeren.

Afbeeldingslocatie: https://i.imgur.com/M4KHO84.jpg?1
klik voor groter, je komt dan in imgur, klik er nog een keer op


De code daarvan is :

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 0011 =  3 = 2^2 - 1
// 0111 =  7 = 2^3 - 1
// 1111 = 15 = 2^4 - 1  etc.
// Met deze benadering valt er een lus te maken.
// Vreemd is wel dat Q7 constant uit blijft, er gaat ergens een bit verloren (in Simulide althans)
// Verwijder je de for-lus en je schrijft alles regel voor regel uit dan gebeurt dat niet, 
// dus met bijv. shiftOut(datapin, clockpin, LSBFIRST, 3); gaat Q7 wel aan. Dit kwam door Pow.
// Pow bleek nodig te zijn om machts te verheffen (in shiftout regel), zie ook toelichting in post. 
// Uren-led U00 blijft net als bij de minuten-led M00 buiten beeld.
// Extra Latchpin aangesloten, dit bleek wmb de makkelijkste oplossing voor deze opstelling.

int latchpin  =  6;      // Pin aangesloten op ST_CP van 74HC595
int clockpin  = 13;     //  Pin aangesloten op SH_CP van 74HC595
int datapin   = 12;    //   Pin aangesloten op DS    van 74HC595
int latchpin2 = A5;   //    Pin aangesloten op ST_CP van 74HC595 Chip2 
int t = 1000;        //     Verander hier de snelheid in milli-seconden

void setup() {
  pinMode(latchpin,  OUTPUT);    // Zet de pinnen op Output
  pinMode(clockpin,  OUTPUT);
  pinMode(datapin,   OUTPUT);
  pinMode(latchpin2, OUTPUT);
}
void loop() {
    delay(t);
  for (int i = 2 ; i < 9 ; i++) {    // Stuur leds chip1 aan
    digitalWrite(latchpin, LOW);    //  Latchpin Laag
    shiftOut  (  datapin, clockpin, LSBFIRST,  pow ( 2 , i )    ); // Resultaat wordt 2^i - 1
    digitalWrite(latchpin, HIGH); //    Latchpin Hoog    
    delay(t);   }                //     delay + einde for-lus

  for (int i = 2 ; i < 6 ; i++) {     // Stuur leds chip2 aan
    digitalWrite(latchpin2, LOW);    //  Latchpin Laag
    shiftOut  (  datapin, clockpin, LSBFIRST,  pow ( 2 , i )    ); // Resultaat wordt 2^i - 1
    digitalWrite(latchpin2, HIGH); //    Latchpin Hoog
    delay(t);   }                 //     delay + einde for-lus       
    
    digitalWrite(latchpin, LOW);        // Latchpin Laag
    shiftOut  (  datapin, clockpin, LSBFIRST, 0  );  // Alle chip1 leds uit
    digitalWrite(latchpin, HIGH);     //   Latchpin Hoog
    digitalWrite(latchpin2, LOW);    //    Latchpin Laag
    shiftOut  (  datapin, clockpin, LSBFIRST, 0  );  // Alle chip2 leds uit
    digitalWrite(latchpin2, HIGH); //      Latchpin Hoog          
}  // return naar void loop()


Volgende stap is ongeveer hetzelfde schema maar het verschil met de vorige opstelling is dat de data vanuit chip1 Q7' naar de DS-pin doorschuift op chip2. Ook is er dan geen extra Latchpin nodig.

Afbeeldingslocatie: https://i.imgur.com/QciBdsI.jpg


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// 0011 =  3 = 2^2 - 1
// 0111 =  7 = 2^3 - 1
// 1111 = 15 = 2^4 - 1  etc.
// Met deze benadering valt er een lus te maken.
// Voor deze sketch heb ik als vorbeeld de functie void blinkAll_2Bytes() gebruikt uit de Arduino Tutorial, code 2.2
// https://www.arduino.cc/en/Tutorial/ShiftOut
// en het bespaart een pin in vergelijking met de vorige opstelling.
// Ipv Pow heb ik nu bit shift toegepast, meer info hier :
// https://forum.arduino.cc/index.php?topic=66146.0 

int latchpin  =  6;      // Pin aangesloten op ST_CP van 74HC595
int clockpin  = 13;     //  Pin aangesloten op SH_CP van 74HC595
int datapin   = 12;    //   Pin aangesloten op DS    van 74HC595
int t = 1000;         //    Verander hier de snelheid in milli-seconden

void setup() {
  pinMode(latchpin, OUTPUT);    // Zet de pinnen op Output
  pinMode(clockpin, OUTPUT);
  pinMode(datapin,  OUTPUT);
}
void loop() {
  delay(t);                                        // Wacht een 'uur'.
  
   digitalWrite(latchpin, 0);                    // Vul chip1 en chip2 met nul.
   shiftOut(datapin, clockpin, LSBFIRST , 0 );
   shiftOut(datapin, clockpin, LSBFIRST , 0 );
   digitalWrite(latchpin, 1);
   
  for (int x = 2; x < 9 ; x++) {            // For-lus voor chip1
    int y = 1 << x;                        //  Bit shift levert een macht van twee (2^x) op.
    y--;                                  //   Verminder 2^x met 1.
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin, LSBFIRST , 0 );   // Vul chip1 met 0.     
    shiftOut(datapin, clockpin, LSBFIRST , y );  //  Vul chip1 met y, de 0 schuift vanuit Q7' door naar chip2.
    digitalWrite(latchpin, 1);
   delay(t);                                   // Wacht een 'uur'.
  }     // Einde eerste for-lus, chip1 zit vol met U00 t/m U07
  
  for (int x = 2; x < 6 ; x++) {           // For-lus voor chip2
    int y = 1 << x;                       // Bit shift levert een macht van twee (2^x) op.
    y--;                                 //  Verminder 2^x met 1.
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin, LSBFIRST , y );     // Vul chip1 met y.
    shiftOut(datapin, clockpin, LSBFIRST , 255 );  //  Vul chip1 met 255, de y schuift vanuit Q7' door naar chip2.
    digitalWrite(latchpin, 1);
   delay(t);                                     // Wacht een 'uur'.
  }    // Einde tweede for-lus , chip1 zit vol met U00 t/m U07 en chip2 zit vol met U08 t/m U11.
  
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin,  LSBFIRST , 0  );   // Uur 0 heeft geslagen, zet de leds uit.
    shiftOut(datapin, clockpin,  LSBFIRST , 0  );
    digitalWrite(latchpin, 1);
    
}   // Return naar void loop.

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
Dit is dan in principe de laatste stap, de vorige opstelling is samengevoegd met de seconden en minuten.

De tijd zou nu minimaal 09 : 41 : 40 en maximaal 09 : 43 : 19 moeten zijn (in stappen van 100 seconden).

Naar mijn theorie moet delay t op 100000 gezet worden om de werkelijke kloksnelheid te benaderen.
Dit heb ik niet de gehele cyclus van 12 uren getest aangezien Simulide een hekel aan grote delays lijkt te hebben en anderzins het ook niet langer als een minuut of 7 volhoudt.
De gehele cycus lijkt wel soepel en in één tempo te lopen als je de delay bijvoorbeeld op 100 zet.

Sowieso is het dan een leuk loop lichtje   Afbeeldingslocatie: http://www.mamjo.com/forum/Smileys/default/smiley.gif


Afbeeldingslocatie: https://i.imgur.com/w4iA96x.jpg
klik voor groter, je komt dan in imgur, klik er nog een keer op


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// De weerstanden zijn afgebeeld als 120 Ohm,in het echt is minstens 220 Ohm te adviseren.
// De klok kan op ieder geheel uur gelijkgesteld worden, stel het is 09:00
// zet dan counter_U op 10 en start de Arduino om 09:00 (Uren 1 hoger, maar niet op 13 zetten, kies dan 1).
// De Q7 van chip2 is 'overgeslagen' omdat dit makkelijker te programmeren bleek.
// Led M00 en U00 zijn niet aangesloten, dit ter indicatie van minuut 60/00 en uur 24/00.

int t = 100;           // Verander hiermee de kloksnelheid (in milliseconden) in één keer.
int counter_U = 1;    //  Counter voor de (12) uren. Bij vooraf INSTELLEN klok, zet deze vanaf 1 T/M 12. Beginstand is 1.
int counter_M = 0;   //   Counter voor de (10) minuten. 

int S00 = 0;  int S10 = 1;   int S20 = 2;   // De seconden leds
int S30 = 3;  int S40 = 4;   int S50 = 5;   // De seconden leds 
int M00 = 6;  int M10 = 7;   int M20 = 8;   // De minuten leds
int M30 = 9;  int M40 = 10;  int M50 = 11;  // De minuten leds    
int latchpin  =  6;      // Pin aangesloten op ST_CP van 74HC595
int clockpin  = 13;     //  Pin aangesloten op SH_CP van 74HC595
int datapin   = 12;    //   Pin aangesloten op DS    van 74HC595

void setup() {   // Zet de pinnen als output.      
  pinMode(S00, OUTPUT) ; pinMode(S10, OUTPUT); pinMode(S20, OUTPUT); 
  pinMode(S30, OUTPUT) ; pinMode(S40, OUTPUT); pinMode(S50, OUTPUT);
  pinMode(M00, OUTPUT) ; pinMode(M10, OUTPUT); pinMode(M20, OUTPUT); 
  pinMode(M30, OUTPUT) ; pinMode(M40, OUTPUT); pinMode(M50, OUTPUT);
  digitalWrite(S00, HIGH);         // S00 aan, deze blijft constant aan.  
  digitalWrite(M00, LOW);         //  M00 uit, deze blijft constant uit.  
  pinMode(latchpin, OUTPUT);     //   Zet de stuurpinnen naar de chips op Output
  pinMode(clockpin, OUTPUT);
  pinMode(datapin,  OUTPUT);   
}
void loop() {
      counter_M++;    // Verhoog de minuten counter met 1
      delay(t);      //     Wacht t seconden  
  for (int s = 1; s < 6; s++) {     // Hier worden de seconden-leds aangezet
    switch (s) {
    case 1: digitalWrite(S10, HIGH); break;
    case 2: digitalWrite(S20, HIGH); break;
    case 3: digitalWrite(S30, HIGH); break;
    case 4: digitalWrite(S40, HIGH); break;
    case 5: digitalWrite(S50, HIGH); break; } // einde switch/case
      delay(t); } // wacht t seconden + einde for-lus
    digitalWrite(S10, LOW);digitalWrite(S20, LOW);digitalWrite(S30, LOW);
    digitalWrite(S40, LOW);digitalWrite(S50, LOW);   // reset de seconden
  if (counter_M == 6) {  // Check of de minuten vol zijn
    digitalWrite(M10, LOW);digitalWrite(M20, LOW);digitalWrite(M30, LOW);
    digitalWrite(M40, LOW);digitalWrite(M50, LOW);  // Reset de minuten
          counter_M = 0;         // reset minuten counter 
          counter_U++;          //  Verhoog de uren counter met 1
      if (counter_U > 1 ) {    //   if-conditie. Na de eerste sec/min ronde,
      Uren();             }   //    spring naar Uren-functie + einde if-conditie voor counter_U.
                      }      //  einde if-conditie voor counter_M
      switch (counter_M) {  // Hier worden de minuten-leds aangezet
      case 1: digitalWrite(M10, HIGH); break;
      case 2: digitalWrite(M20, HIGH); break;
      case 3: digitalWrite(M30, HIGH); break;
      case 4: digitalWrite(M40, HIGH); break;
      case 5: digitalWrite(M50, HIGH); break; } // Einde switch/case
}                     // Return naar void loop

void Uren() {       // Dit is de Uren-functie
     
  for (int u = counter_U ; u < 9 ; u++) {   // For-lus voor chip1
    int y = 1 << u;                        //  Bit shift levert een macht van twee (2^x) op.
    y--;                                  //   Verminder 2^x met 1.
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin, LSBFIRST , 0 );   // Vul chip1 met 0.     
    shiftOut(datapin, clockpin, LSBFIRST , y );  //  Vul chip1 met y, de 0 schuift vanuit Q7' door naar chip2.
    digitalWrite(latchpin, 1);
  if ( u != 8 ) {     // Check of de eerste chip alle U-leds heeft branden, zo ja dan geen return naar void-loop
  return ;      }    //  Einde if-conditie voor u != 8
    }               //   Einde eerste for-lus, chip1 zit vol met U00 t/m U07

  if (counter_U >= 9 && counter_U <= 12) {              // if-conditie om te checken of chip2 chip2 uren-leds moet gaan aanzetten
    for (int u2 = counter_U - 7 ; u2 < 6 ; u2++) {     //  For-lus voor chip2
    int y = 1 << u2;                                  //   Bit shift levert een macht van twee (2^x) op.
    y--;                                             //    Verminder 2^x met 1.
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin, LSBFIRST , y );    //      Vul chip1 met y.
    shiftOut(datapin, clockpin, LSBFIRST , 255 ); //       Vul chip1 met 255, de y schuift vanuit Q7' door naar chip2.
    digitalWrite(latchpin, 1);
  if ( u2 != 5 ) {                              //         Check of de tweede chip 4 U-leds heeft branden, zo ja dan geen return naar void-loop
  return ;       }                             //          Einde if-conditie u2 != 5
  
  }                                          // Einde tweede for-lus , chip1 zit vol met U00 t/m U07 en chip2 zit vol met U08 t/m U11.
  }                                         //  Einde if-conditie counter_U >= 9 && counter_U <= 12

 if (counter_U == 13) {                   //    if-conditie om te testen of er 12 uren zijn verstreken
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin,  LSBFIRST , 0  );   // Het is nu 12 uur, zet de Uren-leds uit.
    shiftOut(datapin, clockpin,  LSBFIRST , 0  );
    digitalWrite(latchpin, 1);
    counter_U = 1;                   // 'Reset' de uren-counter op 1
                      }             //   Einde if-conditie counter_U == 13
 }                                 //    Einde Uren-functie, return naar void loop.


Suggesties ter verbetering van schema en/of code zijn altijd welkom, evenals vragen, het melden van geconstateerde fouten, IRL on-overeenkomstigheden, en etc.
Ben van plan nog een post toe te voegen waarbij de cyclustijd via de seriële monitor wordt getest.
.

[ Voor 0% gewijzigd door kitao op 16-03-2019 17:30 . Reden: spelfout ]


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
De seriele monitor is toegevoegd en de foutjes in de vorige code zijn hersteld. Die code laat ik liever toch staan aangezien de foutjes toch geen invloed hadden en omdat het ook geen papier verspilt.

De afbeelding hieronder is met delay t = 100; Er komt dan gemiddeld 43.120 in beeld.
Dat klopt volgens mij niet met mijn theorie maar heeft wellicht te maken met de Real Speed van 79% in Simulide. Zet ik de delay op 140 dan wordt het iets van 60.450, het is dus een kwestie van afstellen en hopelijk is dat in het echt niet nodig.

Met een als driehoek gezaagd stukje triplex zou met bijvoorbeeld de 12 uren-leds als de basis en de 100 seconden en 10 minuten als de zijden, en met eventueel de driehoek op zn kop gezet, een grappig klokje gemaakt kunnen worden.

Afbeeldingslocatie: https://i.imgur.com/Nk0Tcu7.jpg


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// De weerstanden zijn afgebeeld als 120 Ohm,in het echt is minstens 220 Ohm te adviseren.
// De klok kan op ieder geheel uur gelijkgesteld worden, stel het is 09:00
// zet dan counter_U op 10 en start de Arduino om 09:00 (Uren 1 hoger, maar niet op 13 zetten, kies dan 1).
// De Q7 van chip2 is 'overgeslagen' omdat dit makkelijker te programmeren bleek.
// Led M00 en U00 zijn niet aangesloten, dit ter indicatie van minuut 60/00 en uur 12/00.
// Revisie : Mogelijkheid tot cyclustijd printen toegevoegd en instructies voor Led M00 verwijderd.
// Bron : https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

int t = 100;               // Verander hiermee de kloksnelheid (in milliseconden) in één keer.
int counter_U = 1;        //  Counter voor de (12) uren. Bij vooraf INSTELLEN klok, zet deze vanaf 1 T/M 12. Beginstand is 1. De uren-leds springen pas bij nadat 1 uur is verstreken.
int counter_M = 0;       //   Counter voor de (10) minuten. 
long VorigeMillis = 0;  //    Wordt gebruikt voor de rondetijd
int CC = 0;            //     CyclusCounter om het aantal volledige 12-uurs rondjes te tellen
long cyclustijd = 0;  //      Cyclustijd in milliseconden
int S00 = 0;  int S10 = 1;   int S20 = 2;   // De seconden leds
int S30 = 3;  int S40 = 4;   int S50 = 5;    
int M10 = 7;  int M20 = 8;   int M30 = 9;   // De minuten leds
int M40 = 10; int M50 = 11;                
int latchpin  =  6;      // Pin aangesloten op ST_CP van 74HC595
int clockpin  = 13;     //  Pin aangesloten op SH_CP van 74HC595
int datapin   = 12;    //   Pin aangesloten op DS    van 74HC595

void setup() {   // Zet de pinnen als output.      
  pinMode(S00, OUTPUT) ; pinMode(S10, OUTPUT); pinMode(S20, OUTPUT); 
  pinMode(S30, OUTPUT) ; pinMode(S40, OUTPUT); pinMode(S50, OUTPUT);
  pinMode(M10, OUTPUT);  pinMode(M20, OUTPUT); pinMode(M30, OUTPUT) ; 
  pinMode(M40, OUTPUT);  pinMode(M50, OUTPUT);
  digitalWrite(S00, HIGH);         // Zet S00 aan, deze blijft constant aan.  
  pinMode(latchpin, OUTPUT);      //  Zet de stuurpinnen naar de chips op Output
  pinMode(clockpin, OUTPUT);
  pinMode(datapin,  OUTPUT); 
  Serial.begin(9600);          //     Nodig om de tijd data naar de seriële monitor te versturen. 
}
void loop() {    
      counter_M++;    // Verhoog de minuten counter met 1
      delay(t);      //  Wacht t seconden  
  for (int s = 1; s < 6; s++) {     // Hier worden de seconden-leds aangezet
    switch (s) {
    case 1: digitalWrite(S10, HIGH); break;
    case 2: digitalWrite(S20, HIGH); break;
    case 3: digitalWrite(S30, HIGH); break;
    case 4: digitalWrite(S40, HIGH); break;
    case 5: digitalWrite(S50, HIGH); break; } // einde switch/case
      delay(t); } // wacht t seconden + einde for-lus
    digitalWrite(S10, LOW);digitalWrite(S20, LOW);digitalWrite(S30, LOW);
    digitalWrite(S40, LOW);digitalWrite(S50, LOW);   // reset de seconden
  if (counter_M == 6) {  // Check of de minuten vol zijn
    digitalWrite(M10, LOW);digitalWrite(M20, LOW);digitalWrite(M30, LOW);
    digitalWrite(M40, LOW);digitalWrite(M50, LOW);  // Reset de minuten
          counter_M = 0;         // reset minuten counter 
          counter_U++;          //  Verhoog de uren counter met 1
      if (counter_U > 1 ) {    //   if-conditie. Na de eerste sec/min ronde,
      Uren();             }   //    spring naar Uren-functie + einde if-conditie voor counter_U.
                      }      //     einde if-conditie voor counter_M
      switch (counter_M) {  //      Hier worden de minuten-leds aangezet
      case 1: digitalWrite(M10, HIGH); break;
      case 2: digitalWrite(M20, HIGH); break;
      case 3: digitalWrite(M30, HIGH); break;
      case 4: digitalWrite(M40, HIGH); break;
      case 5: digitalWrite(M50, HIGH); break; } // Einde switch/case
}   // Return naar void loop

void Uren() {  // Dit is de Uren-functie
  for (int u = counter_U ; u < 9 ; u++) {   // For-lus voor chip1
    int y = 1 << u;                        //  Bit shift levert een macht van twee (2^x) op.
    y--;                                  //   Verminder 2^x met 1.
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin, LSBFIRST , 0 );   // Vul chip1 met 0.     
    shiftOut(datapin, clockpin, LSBFIRST , y );  //  Vul chip1 met y, de 0 schuift vanuit Q7' door naar chip2.
    digitalWrite(latchpin, 1);
  if ( u != 8 ) {     // Check of de eerste chip alle U-leds heeft branden, zo ja dan geen return naar void-loop
  return ;      }    //  Einde if-conditie voor u != 8
    }               //   Einde eerste for-lus, chip1 zit vol met U00 t/m U07

  if (counter_U >= 9 && counter_U <= 12) {              // if-conditie om te checken of chip2 uren-leds moet gaan aanzetten
    for (int u2 = counter_U - 7 ; u2 < 6 ; u2++) {     //  For-lus voor chip2
    int y = 1 << u2;                                  //   Bit shift levert een macht van twee (2^x) op.
    y--;                                             //    Verminder 2^x met 1.
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin, LSBFIRST , y );    //      Vul chip1 met y.
    shiftOut(datapin, clockpin, LSBFIRST , 255 ); //       Vul chip1 met 255, de y schuift vanuit Q7' door naar chip2.
    digitalWrite(latchpin, 1);
  if ( u2 != 5 ) {                              //         Check of de tweede chip 4 U-leds heeft branden, zo ja dan geen return naar void-loop
  return ;       }                             //          Einde if-conditie u2 != 5
  
  }                                          // Einde tweede for-lus , chip1 zit vol met U00 t/m U07 en chip2 zit vol met U08 t/m U11.
  }                                         //  Einde if-conditie counter_U >= 9 && counter_U <= 12

 if (counter_U == 13) {                   //    if-conditie om te testen of er 12 uren zijn verstreken
    digitalWrite(latchpin, 0);
    shiftOut(datapin, clockpin,  LSBFIRST , 0  );   // Het is nu 12 uur, zet de Uren-leds uit.
    shiftOut(datapin, clockpin,  LSBFIRST , 0  );
    digitalWrite(latchpin, 1);
    counter_U = 1;                   // 'Reset' de uren-counter op 1
    
//********* Onderstaand codeblokje geeft na één volledige 12-uurs cyclus de rondenummers en de rondetijden.                        ********//
//********* Versturen van data naar de seriele monitor kost tijd, daarom is het beter om dit blokje bij niet-gebruik te commenten. *******//
//********* Dit blokje kan ook verplaatst worden naar de seconden of de minuten-lus.                                                   *******//

    CC++;                                        // Verhoog CyclusCounter met 1
    unsigned long HuidigeMillis = millis();     //  Roept de functie millis() aan en zet de verstreken tijd sinds het starten van de Uno in HuidigeMillis
    cyclustijd = HuidigeMillis - VorigeMillis; //   Bereken de cyclustijd van één ronde. 
    Serial.print("CC ");                      //    Print de letters CC (afkorting voor cycluscounter)
    Serial.print(CC);                        //     Print het nummer in de cycluscounter
    Serial.print("   ");                    //      Print een paar spaties
    Serial.println(cyclustijd);            //       Print de berekende cyclustijd en een wagenterugloop (carriage return).
    VorigeMillis = HuidigeMillis;         //       

//******* Einde ronde tijden codeblokje //          ****************                ****************             ********           *******//                      
                      
                      }               //            Einde if-conditie counter_U == 13
 }                                   //             Einde Uren-functie, return naar void loop.


Zie regel 98
Codeblokje heb ik ingevoegd op regel 35, direkt onder void loop(), en de rondetijden worden 600 bij een delay van 100. (Niet in deze code maar thuis, de code hierboven is hetzelfde gebleven).

Dat lijkt er dan meer op en misschien klopt mijn verwijzing naar real speed 79% niet.
Maar vind dat berekenen persoonlijk niet zo belangrijk en ga weer terug naar mijn vorige bezigheden.

Toch even de telmachine erbij gepakt
60 s x 60 m x 12 u = 43.200
De gemeten 12-uurs cyclustijd was : 43.120
.

[ Voor 2% gewijzigd door kitao op 18-03-2019 04:02 . Reden: Een comment-regel in de code toegevoegd ]


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
jeroen vrij schreef op donderdag 21 maart 2019 @ 10:26:
Ze leveren maar 6mA per output
Als ze alle 8 aan staan.
Daar krijg ik me leds toch niet mee aan.
Die steentjes zijn ook speciaal voor hobby bedoeld, daar hoef je je echt niet druk om te maken of je er wel of geen ledje mee kan aansturen want daar is het juist voor gemaakt, of in ieder geval, daardoor kom je de 74hc595 zo vaak tegen.
Heb er tijd niet naar omgekeken maar op pag.5 par. 7.1 staat een Io van 35 mA.
Per pin is dat volgens mij en dan maakt het volgens mij niet uit of dat er 1 output pin in gebruik is of alle 9.

Bovendien, die chips kosten 2 kwartjes.

En ik noem het steentjes omdat het inderdaad te vergelijken valt met lego-steentjes, de hele 74xx serie kan , zover ik weet en heb ondervonden, allemaal zonder specificatie problemen aan elkaar gekoppeld worden.
Op 5 volt, geen 24.

Afbeeldingslocatie: https://lastminuteengineers.com/wp-content/uploads/2018/07/74HC595-Shift-Register-Working.gif

https://lastminuteenginee...egister-arduino-tutorial/
.

[ Voor 23% gewijzigd door kitao op 21-03-2019 20:00 ]


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 20-05 17:20
jeroen vrij schreef op donderdag 21 maart 2019 @ 22:40:
Geld voor een schuifregister hetzelfde als met de arduino.
Dat als de pin op LOW staat dat dit tevens de ground is dan.
Nee, dat hoeft niet.
Je hebt namelijk shift-registers die sinken en anderen die sturen.
Bij de sink-modellen moet de Led-kathode op de Q0-7.
De 74hc595 heeft daar de anodes op zitten.
Die heeft zn uitgangen Q0-7, afhankelijk van welke data die je daaraan hebt meegegeven, gewoon hoog of laag staan maar als zo'n uitgangspin laag is kan er geen stroom in vloeien omdat die poort daar niet op gebouwd is. Zit diode in waarschijnlijk.

Rode pijltje wijst naar rondje naast inkeping, dat is altijd pin1

Afbeeldingslocatie: https://i.imgur.com/vC4tz3l.jpg?1

Pin14 SER heet op de door mij gebruikte IC de pin14 DS.
Lekker verwarrend allemaal maar verschilt nou eenmaal per fabrikant welke namen ze aan de pinnen geven. Het zou trouwens niet mogen voorkomen dat pin14 bij een andere fabrikant ineens geen DS/SER is.
Niet met dezelfde behuizing althans (package).
.

[ Voor 47% gewijzigd door kitao op 22-03-2019 06:32 ]

Pagina: 1