Arduino stopwatch

Zo moeilijk is een shuifregister niet:

code:


void ShiftByte(char Segments)
{  for(int i = 0; i < 8; i++)
   {  digitalWrite(LED_DATA, (Segments & 0x01) ? HIGH : LOW);
      digitalWrite(LED_CLOCK, HIGH);
      Segments >>= 1;
      digitalWrite(LED_CLOCK, LOW);
   } 
}

Een complete funktie om het display aan te sturen kan er dan zo uitzien:

code:



// Map arduino pin numbers to 74HC595 shift register.
#define LED_DATA  1  // Serial data input for shift register

#define LED_CLOCK 2  // Idle low
                     // High puls shifts data in shift register

#define LED_LATCH 3  // Idle Low
                     // High pulse writes data from shift register to outputs.


void ShiftByte(char Segments)
{  for(int i = 0; i < 8; i++)
   {  digitalWrite(LED_DATA, (Segments & 0x01) ? HIGH : LOW);
      digitalWrite(LED_CLOCK, HIGH);
      Segments >>= 1;
      digitalWrite(LED_CLOCK, LOW);
   } 
}


struct SegmentTableEntry
{  char Ascii;
   char Segments;
};

SegmentTableEntry SegmentTable[] = 
{  { '0', 0b11111100 },
   { '1', 0b01100000 },
   { '2', 0b11011010 },
   { '3', 0b11110010 },
   { '4', 0b01100100 },
   { '5', 0b10110110 },
   { '6', 0b10111110 },
   { '7', 0b11100000 },
   { '8', 0b11111110 },
   { '9', 0b11110110 },
   { ' ', 0b00000000 },
   { '-', 0b00000010 }, 
};

#define NR_ENTRIES(a) (sizeof(a)/sizeof(a[0]))

// Convert Ascii code to segments through table
char GetSegments(char c)
{  for(int i = 0; i < NR_ENTRIES(SegmentTable); i++)
   {  if(SegmentTable[i].Ascii == c)
      {  return SegmentTable[i].Segments;
      }
   }
   
   // Special code for characters that are not in the SegmentTable. 
   return 0b10010010;
}

void UpdateDisplay(char *pBuffer, int NrDigits)
{  pinMode(LED_DATA,  OUTPUT);
   pinMode(LED_CLOCK, OUTPUT);
   pinMode(LED_LATCH, OUTPUT);

   digitalWrite(LED_LATCH, LOW);
   digitalWrite(LED_CLOCK, LOW);

   // Send all data to the shift registers
   for(int i = 0; i < NrDigits; i++)
   {  char Segments = GetSegments(pBuffer[i]);
      ShiftByte(Segments);
   }
   
   // Move data from shift register to output drivers
   digitalWrite(LED_LATCH, HIGH);
   digitalWrite(LED_LATCH, LOW);
}

Klopt, multiplexen is goedkoop en goed te doen.
Maar gaat wel ten koste van de licht opbrengst. Dat rekenmachientje uit 1972 was volledig nutteloos buiten in de zon.

Je kunt een led van 50 jaar geleden niet met een moderne versie gelijkstellen... ;)
Moderne HE leds en displays geven echt nog heel erg veel licht bij multiplexen...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Ik dacht meteen aan een MAX7219 of een MAX7221 die de verbinding legt tussen een Arduino en een 7-segment display. Deze Ic's communiceren met de Arduino over een SPI-bus en ze regelen ook de benodigde stroom die elke digit nodig heeft. Maar daar je segmenten zijn opgebouwd uit 11 LEDs op 12volt denk ik dat het dan beter is om de uitgangen van het IC met een driver zoals een ULN2803 te verbinden. Dit ic kan tot 500mA per kanaal leveren wat wel ruim voldoende is om 11 LEDs te sturen.

Deze link zou je al op weg moeten helpen om je leds aan te sturen.

http://www.learningaboutelectronics.com/Articles/Max7219-4-d...ircuit.php

Depeet

@arco:

In je schema gebruik je een UDN2981. Bij Digikey zie ik dat dit verouderd is. Als we op onze dienst iets moeten ontwerpen proberen we om verouderde IC te mijden. Niet omdat ze slecht zijn maar omdat we de componenten na 10 jaar nog goed kunnen verkrijgen. Ik weet het, 10 jaar is binnen elektronica een eeuwigheid.

Als vervanger voor een UDN2981 kan je een TBD62083 gebruiken. Voor een ULN2803 is TBD62783 een alternatief. Qua pinout en specificaties zijn ze compatible en de dropvoltage is kleiner.
De TBD zijn MOSFETS terwijl een ULN bipolair is.

Depeet
Jochem

Golden Member

Multiplexen kan, en is ook bij displays gebruikelijk. Maar de situatie van TS is wel iets unieker dan het gros van de toepassingen.

Normaal ga je bij multiplexen de stroom verhogen. In geval van TS wil je dat zeker, want de lichtopbrengst is extra belangrijk omdat het bij wedstrijden goed zichtbaar moet blijven.

Omdat TS segmenten heeft met ingebouwde weerstand moet je dan dus de spanning gaan opvoeren. Als je 6 segmenten multiplext dan wordt dat wel heel gortig, want dan zou je toch ergens in de richting van 6x12V moeten gaan. Maar zelfs bij een beperktere spanning (zeg 48V) wordt het allemaal al lastig met je drivers.

Verder is TS een beginner, en het zou kunnen dat hij bij het programmeren van software (of het aansluiten van hardware) iets verkeerd doet, waardoor een voor iets langere duur een segment aan blijft. Dat segment is dan binnen een mum van tijd stuk.

Ik denk dat dat 2 goede redenen zijn om in dit geval schuifregisters te gebruiken in plaats van te multiplexen.

Heb geduld: alle dingen zijn moeilijk voordat ze gemakkelijk worden.

De 2981 is nog gewoon 'active' en in productie: https://www.microchip.com/wwwproducts/en/MIC2981
(zelf gebruik ik meestal losse transistoren)

Ik zie trouwens nergens staan dat er weerstanden in die segmenten zitten?

[Bericht gewijzigd door Arco op 21 augustus 2019 13:40:34 (21%)]

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Op 21 augustus 2019 13:37:52 schreef Arco:
De 2981 is nog gewoon 'active' en in productie: https://www.microchip.com/wwwproducts/en/MIC2981
(zelf gebruik ik meestal losse transistoren)

Ik zie trouwens nergens staan dat er weerstanden in die segmenten zitten?

Ik kijk altijd bij mijn "elektronicaboer". Als die verouderd meldt, wil dat natuurlijk niet zeggen dat ze niet meer leverbaar zijn. Maar ik hou er wel rekening mee dat ze binnen een aantal jaren niet meer worden geproduceerd.
Die TBD's heb ik toevallig gevonden met een vorig projectje. Vond ook drivers die konden sinken en sourcen. Maar een 32-pin SOIC is nou niet echt voor iedereen weggelegd. Ik moet er al helemaal niet aan beginnen :-)

Zondag om 12:35 schreef TS

"Ik wil het graag voor buiten gebruiken, elk digit is inderdaad 4 watt dus zal elk segment 50mA zijn. Hier is geen voorschakelweerstand meer nodig 12V en klaar."

Daar hoeven we dus rekening meer mee te houden ;-)

Depeet

Veel leveranciers (bijv. Farnell) geven soms op dat onderdelen obsolete zijn.
Ze vermelden er dan niet bij dat ze nog wel leverbaar zijn van 20 andere merken... :(

De MIC2981 is nu van Microchip, dus obsolete zal die niet echt gauw worden.

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com
Jochem

Golden Member

Op 21 augustus 2019 13:37:52 schreef Arco:
Ik zie trouwens nergens staan dat er weerstanden in die segmenten zitten?

TS zegt dat ze op 12V werken zonder voorschakelweerstand. Dan concludeer ik dat die intern zitten (een echte stroombron per segment zullen ze wel niet gedaan hebben).

Heb geduld: alle dingen zijn moeilijk voordat ze gemakkelijk worden.

Op 21 augustus 2019 11:43:23 schreef deKees:
Zo moeilijk is een shuifregister niet:

code:


void ShiftByte(char Segments)
{  for(int i = 0; i < 8; i++)
   {  digitalWrite(LED_DATA, (Segments & 0x01) ? HIGH : LOW);
      digitalWrite(LED_CLOCK, HIGH);
      Segments >>= 1;
      digitalWrite(LED_CLOCK, LOW);
   } 
}

Een complete funktie om het display aan te sturen kan er dan zo uitzien:

code:



// Map arduino pin numbers to 74HC595 shift register.
#define LED_DATA  1  // Serial data input for shift register

#define LED_CLOCK 2  // Idle low
                     // High puls shifts data in shift register

#define LED_LATCH 3  // Idle Low
                     // High pulse writes data from shift register to outputs.


void ShiftByte(char Segments)
{  for(int i = 0; i < 8; i++)
   {  digitalWrite(LED_DATA, (Segments & 0x01) ? HIGH : LOW);
      digitalWrite(LED_CLOCK, HIGH);
      Segments >>= 1;
      digitalWrite(LED_CLOCK, LOW);
   } 
}


struct SegmentTableEntry
{  char Ascii;
   char Segments;
};

SegmentTableEntry SegmentTable[] = 
{  { '0', 0b11111100 },
   { '1', 0b01100000 },
   { '2', 0b11011010 },
   { '3', 0b11110010 },
   { '4', 0b01100100 },
   { '5', 0b10110110 },
   { '6', 0b10111110 },
   { '7', 0b11100000 },
   { '8', 0b11111110 },
   { '9', 0b11110110 },
   { ' ', 0b00000000 },
   { '-', 0b00000010 }, 
};

#define NR_ENTRIES(a) (sizeof(a)/sizeof(a[0]))

// Convert Ascii code to segments through table
char GetSegments(char c)
{  for(int i = 0; i < NR_ENTRIES(SegmentTable); i++)
   {  if(SegmentTable[i].Ascii == c)
      {  return SegmentTable[i].Segments;
      }
   }
   
   // Special code for characters that are not in the SegmentTable. 
   return 0b10010010;
}

void UpdateDisplay(char *pBuffer, int NrDigits)
{  pinMode(LED_DATA,  OUTPUT);
   pinMode(LED_CLOCK, OUTPUT);
   pinMode(LED_LATCH, OUTPUT);

   digitalWrite(LED_LATCH, LOW);
   digitalWrite(LED_CLOCK, LOW);

   // Send all data to the shift registers
   for(int i = 0; i < NrDigits; i++)
   {  char Segments = GetSegments(pBuffer[i]);
      ShiftByte(Segments);
   }
   
   // Move data from shift register to output drivers
   digitalWrite(LED_LATCH, HIGH);
   digitalWrite(LED_LATCH, LOW);
}

Zijn hier nog bepaalde bibliotheek bestanden voor nodig?

Lees die code nou even, dan zie je dat toch vanzelf?! Zie je ergens functies oid die niet in de code zelf staan?

ps, quote van die hele lap is niet zo nuttig.

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

Golden Member

Lees die code nou even, dan zie je dat toch vanzelf?! Zie je ergens functies oid die niet in de code zelf staan

Ik gok dat TS tenauwernood weet wat een functie is :?

De jongere generatie loopt veel te vaak zijn PIC achterna.

Weet jij het? aangezien de TS een beginner is kun je het hem misschien eens uitleggen of uitleggen waar hij moet op letten om dat te zien :p

LDmicro user.

Het lijkt me dat ie toch wel iets van Arduino weet, gezien de ambitie van zo'n project. Dan zul je toch een beetje moeten kunnen programmeren. We wachten het eerst maar even af.

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

Helaas nog niet verder gekomen dan dit. Heeft iemand nog een idee hoe ik aan een programma kan komen? Zelf kom ik er niet uit om hier iets voor te schrijven.

Gr.

Wat is 'dit' dan precies? Er zijn hier een aantal mogelijkheden genoemd. Daar kun je dan een oplossing uit kiezen. Met alleen een programma heb je ook nog niks.

Een programma schrijven voor een PIC 16F876/877/886/887 wil ik wel doen, maar ik hou mijn hart vast voor de rest van het project want grote display's vragen ook wel wat kennis op hardware gebied.

LDmicro user.

Op 7 oktober 2019 09:22:47 schreef MGP:
Een programma schrijven voor een PIC 16F876/877/886/887 wil ik wel doen, maar ik hou mijn hart vast voor de rest van het project want grote display's vragen ook wel wat kennis op hardware gebied.

Inmiddels ben ik al aardig op weg en heb een schema die ik heb na gebouwd en klaar is. Echter zit daar een pic in die ik dus niet kan programmeren. Ik had daar iemand voor maar die gene is erg druk dus het blijft hangen daar op. Aankomend weekend heb ik een wedstrijd waar ik hem graag bij wil gebruiken. In de bijlage een schema die ik gebouwd heb. Verder is mijn bord klaar op de ene PIC na :) ;(

Wow, mooi gemaakt.

7 cijfers? voor wat dienen die?

En welk toetsen heb je daar, voor wat dienen die?

Tegen het weekend? absoluut geen druk ;)

LDmicro user.

De 2 groene digits zijn ronde tellers en de 5 rode digits zijn voor de stopwatch. Hier heb ik er 5 voor gebruikt omdat een wedstrijd niet langer duurt dan 9 uur dus dat scheelde ruimte gewicht enz.

De bediening voor de stopwatch zou als volgt moeten zijn.

Start knop
Stop knop
Reset knop

En de werking van de teller.

Knop voor +1
Knop voor -1
Reset knop naar 00

De bediening gebeurd door een remote control vandaar de relai als schakelaars.

Gr.

Dat zijn dan 6 ingangen en geen 4 zoals in uw tekening of gebruik je de + en - knop voor de reset als je ze gezamenlijk indrukt?

Is de print al gemaakt?

LDmicro user.

Volgens mij werkt het zo valt er 1 signaal weg dan is het start of de andere dan ist stop en de beide signalen dan is het reset kan dat?

En ja de printplaat is klaar zit al in de behuizing enkel de pic op de ic voet drukken.

Je moet dat niet aan mij vragen hoe het werkt, ik moet het zeker weten.

Ik ga er voorlopig vanuit dat je een NC contact hebt voor start en stop en als je beiden indrukt krijg je na bv. 1sec een reset.
Ik zou NO contacten kiezen, maargoed...

Ik wil ook pin27 gebruiken ipv 6 voor digitselectie, voor de eventuele programmering speelt dat geen rol.. spoortje onderbreken en draadje leggen?

Je zult ook een 20Mhz kristal nodig hebben en een 16F876a die pin compatibel is, de enige 28pins die ik heb om te proberen.

Kun je zelf de pic programmeren als je het (hex)programma krijgt of laten programmeren? anders mag je het uitsluiten voor dit weekend en eventuele aanpassingen.

edit: mijn 16F876a zijn allemaal smd exemplaren, die kun je waarschijnlijk niet gebruiken(opsturen) en zul je die zelf moeten kopen en (laten) programmeren, dat kan bij Voti, zie advertentie op CO.

LDmicro user.

Oke.

Ik kan zelf geen pic programmeren wel ooit eens een k150 gekocht maar daar bij gebleven. Dit gaat dus ook nog niet lukken voor deze week. Zelf kwam ik ook nog een schema tegen van een stopwatch misschien werkt dit ook wel als ik er nog 2 digits bij aan knoop en de ms er alleen in zet voor de door telling want die telt toch tot 99?

Het liefst ga ik voor een PIC16F882 die iemand voor mij kan en wil programmeren. Uiteraard voor niets gaat de zon op :P

Een 882 kan voor mij niet door de beperkte controllerkeuze van het programma en dus laat ik het verder aan u over.

Dat nieuw schema is in mijn ogen niet betrouwbaar genoeg maar ik kan het ook mis hebben.

Toch een prachtige realisatie van die klok _/-\o_

NB. Waar heb je die segmenten gekocht?

LDmicro user.