wachttijd verstoort multiplex 7segment display

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 5
Geregistreerd: 30 Dec 2016, 09:38

wachttijd verstoort multiplex 7segment display

Berichtdoor supafly1975 » 30 Dec 2016, 09:46

Hey,
Ik ben niet zo'n specialist in Arduino IDE, en ben ook maar een amateur electronicus... :)

Ik zit met het volgende probleem :
Ik schreef een Smartphone App, met appinventor, die elke seconde een integer+newline (\n) verstuurt over bluetooth naar een Arduino met bluetooth-shield van Adafruit.
Deze stuurt deze code terug, wat perfect werkt. De arduino moet vervolgens deze integer op een gemultiplexed 4 digit 7segment display tonen, en daar loopt het fout.
Bij het versturen van bv. 1234 knippert 123 heel kort op het scherm, en de 4 blijft branden.

Ik vermoed dat dit komt doordat de Arduino telkens wacht op de Serial data.
Hoe los ik dit probleem op? (Het zal hem vooral in de onderste 2 loops zitten vermoed ik, maar ik heb er geen idee van hoe ik dit oplos)

Thanks!
Peter

De Arduino-code vind je hieronder :
cpp code
/*
gets data from own software (4 digits + #10)
and translates into 7 segment displays.
Also returns received data to computer.
*/

String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete

int time = 5;
int pinA = 2;
int pinB = 3;
int pinC = 4;
int pinD = 5;
int pinE = 6;
int pinF = 7;
int pinG = 8;
int pinDP = 9;
int DIG1 = 10;
int DIG2 = 11;
int DIG3 = 12;
int DIG4 = 13;

void setup() {
// initialize serial:

pinMode(pinA,OUTPUT);
pinMode(pinB,OUTPUT);
pinMode(pinC,OUTPUT);
pinMode(pinD,OUTPUT);
pinMode(pinE,OUTPUT);
pinMode(pinF,OUTPUT);
pinMode(pinG,OUTPUT);
pinMode(pinDP,OUTPUT);
pinMode(DIG1,OUTPUT);
pinMode(DIG2,OUTPUT);
pinMode(DIG3,OUTPUT);
pinMode(DIG4,OUTPUT);

Serial.begin(9600);
Serial.println("KFCM Logo Software P.DUYCK");


}

void choose_digit(char num) {
switch(num) {
default: // 0 default value
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, LOW);
digitalWrite(pinDP,LOW); break;
case 1:
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
digitalWrite(pinDP,LOW); break;
case 2:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, LOW);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, LOW);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;
case 3:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;
case 4:
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;
case 5:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, LOW);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, LOW);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;
case 6:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, LOW);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;
case 7:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
digitalWrite(pinDP, LOW); break;
case 8:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;
case 9:
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, LOW);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
digitalWrite(pinDP, LOW); break;

}

}

void pick_digit(int digit) {
digitalWrite(DIG1, LOW);
digitalWrite(DIG2, LOW);
digitalWrite(DIG3, LOW);
digitalWrite(DIG4, LOW);
switch(digit) {
case 1: digitalWrite(DIG1, HIGH); break;
case 2: digitalWrite(DIG2, HIGH); break;
case 3: digitalWrite(DIG3, HIGH); break;
default:digitalWrite(DIG4, HIGH); break;
}

}

void decimal_place() {
digitalWrite(pinDP, HIGH);
}

void seven_segment(int number) {
unsigned char thousands = int (number/1000);
unsigned char hundreds = int ((number/100)%10);
unsigned char tens = int ((number/10)%10);
unsigned char ones = int (number%10); //1234
choose_digit(thousands);
pick_digit(1);
delay(time);
choose_digit(hundreds);
pick_digit(2);
delay(time);
choose_digit(tens);
pick_digit(3);
delay(time);
choose_digit(ones);
pick_digit(4);
delay(time);

}




void loop() {
// print the string when a newline arrives:
if (stringComplete) {
inputString.trim();
seven_segment(inputString.toInt());
// clear the string:
stringComplete = false;
inputString="";
;
}
}

/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}

Advertisement

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor nicoverduin » 30 Dec 2016, 12:03

Alvast een paar opmerkingen over de code:
a) gebruik af en toe de CTRL-T functie in de IDE dan springt de code netjes in en wordt deze geformatteerd
b) Bij pin definities gebruik const ervoor. Dat scheelt weer 2 bytes ram geheugen per pin
c) Vermijd String zoveel mogelijk omdat de Arduino geen garbage collection heeft waardoor het RAM geheugen gefragmenteerd raakt. Nu gaat het mogelijk goed maar je krijgt onvoorspelbare fouten ooit.
d) time is vlgs mij ook een systeem variabele. Dat kan verkeerde uitkomsten geven. Ik zou die gelijk vervangen voor een andere naam

Dan jouw code:
SerialEvent wordt aangeroepen als er iets binnen is. En daarna ga je wachten tot de rest binnen is. Je kan ook alleen het teken binnen lezen (ik zou daar gelijk een char array van maken) en kijken of het een '\n' is en zet je stringComplete true. Anders false. Dan zit je niet meer te wachten tot alles binnen is.

Je gebruikt allemaal 'dure' String functies die ten koste gaan van de processor tijd.

In de loop converteer je de string naar cijfers en toont deze op het display en daar na zeg je dat deze false is. Daarna loop je de cijfers niet meer af. Dus zal de laatste blijven branden. en de andere voor 5mS.

Er moet nogal eea veranderen.

Je hebt in feite 2 hoofdfuncties:
a) toon op display. Deze moet zijn cijfers uit een tabel halen (meest eenvoudige). Daar staat de juiste waarde totdat er een nieuw reeks getallen is ontvangen.
b) ontvangen van tekens (de serialEvent). Deze zet de tekens in een char array oid. en houdt de stringComplete op false totdat er een newline is ontvangen. Na de newline kun je dan de conversie uitvoeren en de cijfer array invullen. Het tonen moet dus los van deze functie gebeuren.

Omdat delay dodelijk is in dit soort oplossingen is het beter om een timer te gebruiken die elke keer als deze is verlopen naar het volgende digit gaat en de juiste pin aanstuurt. Zie hiervoor blink without delay.

Of..... je googled even omdat er heel veel voorbeelden al zijn van 7 segment displays.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 270
Geregistreerd: 30 Dec 2012, 11:42

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor Rudi » 30 Dec 2016, 17:45

Los van de terechte opmerkingen van Nico, zit de oorzaak van het probleem waarschijnlijk in de pick_digit() routine. Je zet heel even DIG1, DIG2 of DIG3 aan afhankelijk van switch(digit) maar de volgende keer dat deze routine wordt doorlopen zet je ze allen (DIG1 t/m DIG4) terug uit en de volgende aan. Als het niet DIG1, 2 of 3 is zet je ook DIG4 wel uit maar daarna steeds terug aan. Wat zich in de praktijk vertaalt als even oplichten van de eerste drie digits en voor het oog constant aanblijven van de vierde.

cpp code
void pick_digit(int digit) {
digitalWrite(DIG1, LOW);
digitalWrite(DIG2, LOW);
digitalWrite(DIG3, LOW);
digitalWrite(DIG4, LOW);
switch(digit) {
case 1: digitalWrite(DIG1, HIGH); break;
case 2: digitalWrite(DIG2, HIGH); break;
case 3: digitalWrite(DIG3, HIGH); break;
default:digitalWrite(DIG4, HIGH); break;
}
Arduinows!
Why do computer programmers confuse Halloween with Christmas? Because Oct 31 = Dec 25
I got 01100011 problems but a bit ain't 00000001

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor shooter » 30 Dec 2016, 19:22

de call naar de sevensegment moet niet in de IF maar gewoon in de loop.
paul deelen
shooter@home.nl

Berichten: 5
Geregistreerd: 30 Dec 2016, 09:38

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor supafly1975 » 30 Dec 2016, 20:40

Opgelost... Hoorde inderdaad niet in de IF-functie...
En alvorens inputstring werd leeggemaakt, nam ik die over in een andere string...

Werken met strings is voor mij handigst, er hoort ook een feedback naar de app te gebeuren om te bevestigen dat de nieuwe waarde goed is ontvangen...

Het inspringen is ondertussen ook gebeurd :) Dit kwam omdat een groot deel van de code 'geleend' werd van gegoogle-de websites :)

Bedankt voor de hulp allemaal!

Fijn eindejaar!
En een goed begin!

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor nicoverduin » 30 Dec 2016, 20:52

Handiger wel...maar je gaat een keer mank en dan met onverklaarbare resultaten. Je kan ook gewoon char arrays gebruiken.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 5
Geregistreerd: 30 Dec 2016, 09:38

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor supafly1975 » 12 Jan 2017, 11:27

Nog een bijhorend vraagje over interrupts...

De software op mijn smartphone stuurt nu elke seconde de 4 te tonen digits naar het scorebord, ook als er niks wijzigt.
Op het einde van elke loop() gaat de software even door de serial-data en toont de nieuwe waarde gedurende 1 seconden enzovoort...

Hoe kan ik in de arduino ervoor zorgen dat er enkel iets nieuws getoond word als de 4 digits + #10 zijn ontvangen?

Ik zou de software aanpassen dat hij niet elke seconde meer uitstuurt, maar enkel als iets in de 4 digits wijzigen...
Hoe laat ik mijn Arduino kijken of hij iets ontvangt, terwijl hij wel de loop van het multiplexen blijft doorlopen? Interrupts of zo?
Als ik nu stop met uitzenden, springt de display na 1 seconde op 0000...

gr,
P.

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: wachttijd verstoort multiplex 7segment display

Berichtdoor shooter » 12 Jan 2017, 13:28

die seven_segments call moet buiten de if.
want anders zie je niks.
paul deelen
shooter@home.nl

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Google [Bot] en 20 gasten