Hulp efficientie arduino code

Arduino specifieke Software
Berichten: 5
Geregistreerd: 09 Aug 2016, 23:24

Hulp efficientie arduino code

Berichtdoor Njick » 09 Aug 2016, 23:32

Hallo allemaal,

Ik ben bezig met het maken van een led equalizer met een MSGEQ7 en een aantal 4017's. Hiervoor heb ik een code geschreven die werkt, maar veel te sloom is.
Mijn probleem is dat elke 7 frequenties die uit de MSGEQ7 komen een for loop moeten laten lopen tot de waarde van die frequentie bereikt is. Maar omdat hij dit elke loop 7 keer moet doen wordt de snelheid van elke loop traag.
Hierdoor is er een ''Flicker'' effect te zien, daarom heb ik wat hulp nodig met het optimaliseren van mijn arduino code. Hoe kan ik mijn code ''sneller'' de loop kunnen laten herhalen zonder functionaliteit te verliezen?
Ik gebruik voor elk van de 7 frequenties uit de MSGEQ7 een clock pin en een reset pin.

Alvast bedankt,

Nick

cpp code
int analogPin = A0; // read from multiplexer using analog input 0
int strobePin = 8; // strobe is attached to digital pin 2
int MSGResetPin = 9; // reset is attached to digital pin 3
int spectrumValue; // to hold a2d values
int clockPin = 52;
int clockPin1 = 50;
int clockPin2 = 48;
int clockPin3 = 46;
int clockPin4 = 44;
int clockPin5 = 42;
int clockPin6 = 40;
int resetPin = 53;
int resetPin1 = 51;
int resetPin2 = 49;
int resetPin3 = 47;
int resetPin4 = 45;
int resetPin5 = 43;
int resetPin6 = 41;

void setup()
{
pinMode(analogPin, INPUT);
pinMode(strobePin, OUTPUT);
pinMode(MSGResetPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(clockPin1, OUTPUT);
pinMode(clockPin2, OUTPUT);
pinMode(clockPin3, OUTPUT);
pinMode(clockPin4, OUTPUT);
pinMode(clockPin5, OUTPUT);
pinMode(clockPin6, OUTPUT);
pinMode(resetPin, OUTPUT);
pinMode(resetPin1, OUTPUT);
pinMode(resetPin2, OUTPUT);
pinMode(resetPin3, OUTPUT);
pinMode(resetPin4, OUTPUT);
pinMode(resetPin5, OUTPUT);
pinMode(resetPin6, OUTPUT);
analogReference(DEFAULT);
digitalWrite(resetPin, LOW);
digitalWrite(strobePin, HIGH);
}

void loop()
{
digitalWrite(MSGResetPin, HIGH);
digitalWrite(MSGResetPin, LOW);


digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var1 = 0; var1 < PWMvalue; var1 = var1 + 1) {
clock();
}
reset();

digitalWrite(strobePin, HIGH);
digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue1 = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var2 = 0; var2 < PWMvalue1; var2 = var2 + 1) {
clock1();
}

reset1();
digitalWrite(strobePin, HIGH);
digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue2 = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var3 = 0; var3 < PWMvalue2; var3 = var3 + 1) {
clock2();
}
reset2();

digitalWrite(strobePin, HIGH);
digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue3 = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var4 = 0; var4 < PWMvalue3; var4 = var4 + 1) {
clock3();
}
reset3();

digitalWrite(strobePin, HIGH);
digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue4 = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var5 = 0; var5 < PWMvalue4; var5 = var5 + 1) {
clock4();
}
reset4();

digitalWrite(strobePin, HIGH);
digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue5 = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var6 = 0; var6 < PWMvalue5; var6 = var6 + 1) {
clock5();
}
reset5();

digitalWrite(strobePin, HIGH);
digitalWrite(strobePin, LOW);
spectrumValue = analogRead(analogPin);
int PWMvalue6 = spectrumValue / 40; // scale analogRead's value to Write's 25 max
for (int var7 = 0; var7 < PWMvalue6; var7 = var7 + 1) {
clock6();
}

digitalWrite(strobePin, HIGH);




reset6();
}

void clock() {
digitalWrite(clockPin, HIGH);
delay(1);
digitalWrite(clockPin, LOW);
}
void clock1() {
digitalWrite(clockPin1, HIGH);
delay(1);
digitalWrite(clockPin1, LOW);
}
void clock2() {
digitalWrite(clockPin2, HIGH);
delay(1);
digitalWrite(clockPin2, LOW);
}
void clock3() {
digitalWrite(clockPin3, HIGH);
delay(1);
digitalWrite(clockPin3, LOW);
}
void clock4() {
digitalWrite(clockPin4, HIGH);
delay(1);
digitalWrite(clockPin4, LOW);
}
void clock5() {
digitalWrite(clockPin5, HIGH);
delay(1);
digitalWrite(clockPin5, LOW);
}
void clock6() {
digitalWrite(clockPin6, HIGH);
delay(1);
digitalWrite(clockPin6, LOW);
}



void reset() {
digitalWrite(resetPin, HIGH);
digitalWrite(resetPin, LOW);
}
void reset1() {
digitalWrite(resetPin1, HIGH);
digitalWrite(resetPin1, LOW);
}
void reset2() {
digitalWrite(resetPin2, HIGH);
digitalWrite(resetPin2, LOW);
}
void reset3() {
digitalWrite(resetPin3, HIGH);
digitalWrite(resetPin3, LOW);
}
void reset4() {
digitalWrite(resetPin4, HIGH);
digitalWrite(resetPin4, LOW);
}
void reset5() {
digitalWrite(resetPin5, HIGH);
digitalWrite(resetPin5, LOW);
}
void reset6() {
digitalWrite(resetPin6, HIGH);
digitalWrite(resetPin6, LOW);
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Hulp efficientie arduino code

Berichtdoor Koepel » 10 Aug 2016, 05:08

Hallo,

Je zet een waarde in de 4017 met een clock en geeft dan een reset.
Is dat de bedoeling ? Bij die reset valt de uitgang toch weer terug naar de beginstand ?
Zou het niet logischer zijn om eerst een reset te geven, en dan met de clock het aantal pulsen te geven ?

Kan jouw 4017 een led aansturen ?
Een 74HC595 kan eventueel wel leds aansturen, en er zijn '595' shift registers die nog meer stroom kunnen leveren, zoals de TPIC6B595 of TPIC6C595 : https://www.adafruit.com/products/457

Je kunt je sketch eenvoudiger te maken door de loop() in twee delen te splitsen. Een deel dat de informatie ophaalt en een deel dat uitvoert. Dat is in deze situatie nog niet zo heel voordelig, omdat de MSGE07 een bepaalde pulsbreedte nodig heeft. Dus zul je delays moeten toevoegen met delayMicroseconds(), zoals hier is gedaan : http://www.eetimes.com/author.asp?doc_id=1323030

Ik weet niet of dit voorbeeld klopt, ik heb niet goed in de datasheet gekeken wanneer de strobe hoog of laag is.
Code: Alles selecteren
int band[7];
...
  for( int i=0; i<7; i++)
  {
    digitalWrite( strobePin, LOW);
    delayMicroseconds( 18);
    digitalWrite( strobePin, HIGH);
    delayMicroseconds( 72 - 18);

    band[i] = analogRead( analogPin);
  }


Voor de 4017 is die delay van 1 milliseconde toch niet nodig ? Dat zijn 1000 microseconden. Een CD4017 is wat langzamer en een 74HC4017 is wat sneller, maar beide hebben volgens mij geen delay nodig. Als je toch een delay wilt, begin dan met 10 microseconden : delayMicroseconds(10)

Je kunt een functie maken van clock en reset. Als beiden geen delay, of dezelfde delay hebben, dan is één functie voldoende voor beide.
Code: Alles selecteren
void Pulse( int pin)
{
  digitalWrite( pin, HIGH);
  // delayMicroseconds( 10);
  digitalWrite( pin, LOW);
}


Het aanroepen gaat dan door de pin als parameter te gebruiken:
Code: Alles selecteren
  Pulse( clockPin);
  Pulse( resetPin);
  Pulse( clockPin1);
  Pulse( resetPin1);


Je kunt ook de pin nummers in een array plaatsen. Een array begint bij index 0.
Ik heb meteen het keyword 'const' ervoor gezet, het gaat om integers die constanten zijn.
Code: Alles selecteren
const int clockPins[7] = { 52, 50, 48, 46, 44, 42, 40 };
const int resetPins[7] = { 53, 51, 49, 47, 45, 43, 41 };


Het aanroepen wordt dan:
Code: Alles selecteren
  Pulse( clockPins[0]);
  Pulse( resetPins[0]);
  Pulse( clockPins[1]);
  Pulse( resetPins[1]);


Vervolgens de 4017 in een loop zetten.
De variabele die langs de 4017s gaat heet hier 'j'. Ik zou het liever "mijn4017" noemen of zo, maar dat wordt wat lang.
Code: Alles selecteren
  for( int j=0; j<7; j++)
  {
    int spectrumValue = band[j];
    int PWMvalue = spectrumValue / 40;
    Pulse( resetPins[j]);
    for( int var = 0; var < PWMvalue; var++)
    {
      Pulse( clockPins[j]);
    }
  }


Als je iets hebt dat een beetje werkt, sla het dan op als sketch en ga verder met een nieuwe sketch. Het is normaal als je tijdens het ontwikkelen van een sketch een stuk of 5 verschillende sketches hebt. Probeer eens wat uit met de functies en arrays.

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

Re: Hulp efficientie arduino code

Berichtdoor shooter » 10 Aug 2016, 12:00

een 4017 kan maar tot 10 tellen, dus je moet de spectrumvalue delen door 100.
je kunt ook eerst alle waardes ophalen uit de msgeq7 en dan naar een display werken.

verder kun je met 1 for loop (van 1 tot 10 ) alle uitgangen tegelijk bedienen, door te kijken of er een puls moet komen of niet, dus niet 10 losse stukken, maar alles tegelijk.
en vlak voordat je begint met schrijven resetten (en dat kan dan ook allemaal tegelijk) dan zet je als alles goed staat een delay (of beter een timer) in om de waardes even te laten staan.
bijvoorbeeld 100 milliseconden)
ik vind 4017 trouwens verkeerde keuze, omdat er maar 1 segment aan is.


Als uitbreiding kun je zelfs balken overslaan als ze nog steeds hetzelfde zijn.
paul deelen
shooter@home.nl

Berichten: 5
Geregistreerd: 09 Aug 2016, 23:24

Re: Hulp efficientie arduino code

Berichtdoor Njick » 10 Aug 2016, 13:05

Heel erg bedankt Koepel en Shooter!

Door alleen de delay weg te halen bij de clockpins is het flikker effect al weg!
Shooter, de waarde deel ik door 40 omdat ik 3 CD4017's heb ''gecascade'' waardoor ik voor elke band 24 leds heb.
Toch kon ik het niet laten om al deze nuttige informatie links te laten liggen en ben ik gaan proberen alles toe te passen.
Voor mijn gevoel zou alles moeten werken in dit vernieuwde stukje code, maar toch doet hij het niet helemaal.
Ik heb getest of er een waarde uit komt uit de PWMValue en dat komt er, maar het schrijven op de pins met de array's doet hij volgens mij niet.

Feedback would be appreciated :)

Code: Alles selecteren
int analogPin = A0; // read from multiplexer using analog input 0
int strobePin = 8; // strobe is attached to digital pin 2
int MSGResetPin = 9; // reset is attached to digital pin 3
int spectrumValue; // to hold a2d values
int clockPins[7] = {52, 50, 48, 46, 44, 42, 40 };
int resetPins[7] = {53, 51, 49, 47, 45, 43, 41 };
int band[7];

void setup()
{
  pinMode(analogPin, INPUT);
  pinMode(strobePin, OUTPUT);
  pinMode(MSGResetPin, OUTPUT);
  pinMode(clockPins[7], OUTPUT);
  pinMode(resetPins[7], OUTPUT);
  digitalWrite(MSGResetPin, LOW);
  digitalWrite(strobePin, HIGH);
}

void loop()
{
  for ( int j = 0; j < 7; j++)
  {
    digitalWrite(MSGResetPin, HIGH);
    digitalWrite(MSGResetPin, LOW);
    digitalWrite(strobePin, LOW);
    spectrumValue = analogRead(analogPin);
    int PWMvalue = spectrumValue / 40; // scale analogRead's value to Write's 25 max
    band[j] = PWMvalue;
    for (int var1 = 0; var1 < band[j]; var1 = var1 + 1) {
      Pulse(clockPins[j]);
    }
    Pulse(resetPins[j]);
  }
  digitalWrite(strobePin, HIGH);
}

void Pulse(int pin) {
  digitalWrite(pin, HIGH);
  digitalWrite(pin, LOW);
}


Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Hulp efficientie arduino code

Berichtdoor Koepel » 10 Aug 2016, 14:57

Toch zou ik eerst de reset pulse geven, en daarna pas een aantal strobe pulsen.
Kun je de reset puls geven voor de loop met var1 ? Werkt het dan nog steeds ?

De zeven clock en reset pinnen als OUTPUT zetten kan alleen stuk voor stuk.
Bijvoorbeeld het array van clockPins[] heeft 7 elementen, van [0] tot en met [6].
Als je dit doet:
Code: Alles selecteren
pinMode(clockPins[7], OUTPUT);

Dan zet je alleen de clockPins[7] als output, want dat is maar één integer uit het array, terwijl index 7 niet eens bestaat.

De pinMode() functie kan maar één pin tegelijk doen, en niet een hele reeks.

Dus gewoon stuk voor stuk:
Code: Alles selecteren
  for( int i=0; i<7; i++)             // count from 0 up to 6
  {
    pinMode(clockPins[i], OUTPUT);
    pinMode(resetPins[i], OUTPUT);
  }


Je hebt het keyword 'const' niet gebruikt ? De compiler vind je een stuk aardiger als je dat wel doet :lol:

Berichten: 5
Geregistreerd: 09 Aug 2016, 23:24

Re: Hulp efficientie arduino code

Berichtdoor Njick » 10 Aug 2016, 21:19

Koepel schreef:Toch zou ik eerst de reset pulse geven, en daarna pas een aantal strobe pulsen.
Kun je de reset puls geven voor de loop met var1 ? Werkt het dan nog steeds ?

De zeven clock en reset pinnen als OUTPUT zetten kan alleen stuk voor stuk.
Bijvoorbeeld het array van clockPins[] heeft 7 elementen, van [0] tot en met [6].
Als je dit doet:
Code: Alles selecteren
pinMode(clockPins[7], OUTPUT);

Dan zet je alleen de clockPins[7] als output, want dat is maar één integer uit het array, terwijl index 7 niet eens bestaat.

De pinMode() functie kan maar één pin tegelijk doen, en niet een hele reeks.

Dus gewoon stuk voor stuk:
Code: Alles selecteren
  for( int i=0; i<7; i++)             // count from 0 up to 6
  {
    pinMode(clockPins[i], OUTPUT);
    pinMode(resetPins[i], OUTPUT);
  }


Je hebt het keyword 'const' niet gebruikt ? De compiler vind je een stuk aardiger als je dat wel doet :lol:


Top! Super bedankt voor alle hulp en tijd die je hebt besteed om mij te helpen! :D
De code werkt nu prima, en trouwens, ik heb geprobeerd om de reset eerst te doen maar op een een of andere manier vind de 4017 dat niet leuk.
Hij flikkert super erg als ik de reset voor de for loop zet en als ik hem erna zet werkt hij super!

Nick

Berichten: 5
Geregistreerd: 09 Aug 2016, 23:24

Re: Hulp efficientie arduino code

Berichtdoor Njick » 10 Aug 2016, 21:34

Edit: Ik kom er net achter dat hij op elke 7 output pinnen de outputs van band1 en band7 uit de MSGEQ7 output... er klopt nog iets niet helemaal.
Back to debugging, yay :D

Code: Alles selecteren
int analogPin = A0; // read from multiplexer using analog input 0
int strobePin = 8; // strobe is attached to digital pin 2
int MSGResetPin = 9; // reset is attached to digital pin 3
int spectrumValue; // to hold a2d values
const int clockPins[7] = {52, 50, 48, 46, 44, 42, 40 };
const int resetPins[7] = {53, 51, 49, 47, 45, 43, 41 };
int band[7];

void setup()
{
  pinMode(analogPin, INPUT);
  pinMode(strobePin, OUTPUT);
  pinMode(MSGResetPin, OUTPUT);
  digitalWrite(MSGResetPin, LOW);
  digitalWrite(strobePin, HIGH);
}

void loop()
{
  for ( int j = 0; j < 7; j++)
  {
    pinMode(clockPins[j], OUTPUT);
    pinMode(resetPins[j], OUTPUT);
    digitalWrite(MSGResetPin, HIGH);
    digitalWrite(MSGResetPin, LOW);
    digitalWrite(strobePin, LOW);
    spectrumValue = analogRead(analogPin);
    int PWMvalue = spectrumValue / 40; // scale analogRead's value to Write's 25 max
    band[j] = PWMvalue;
    Pulse(resetPins[j]);
    for (int var1 = 0; var1 < band[j]; var1 = var1 + 1) {
      Pulse(clockPins[j]);
    }
  }
  digitalWrite(strobePin, HIGH);
}

void Pulse(int pin) {
  digitalWrite(pin, HIGH);
  digitalWrite(pin, LOW);
}

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Hulp efficientie arduino code

Berichtdoor Koepel » 10 Aug 2016, 22:48

Kun je de pinMode voor die pinnen in setup() zetten ? Dan krijg je dus een for-loop in setup() en in loop().

Je kunt wat gegevens naar de seriele monitor schrijven.
Een Serial.begin(9600) in setup(), en daarna in loop() bijvoorbeeld PWMvalue naar de seriele monitor sturen.

Ik heb zelf geen MSGEQ7, dus ik kan het niet proberen.
Kun je nagaan wat de delays zijn ? Dat staat in de datasheet. Ik vermoed dat er op een paar plaatsen een delay nodig is.

Dat de reset voor de for-loop niet goed werkt, dat begrijp ik niet. Maar het is dan ook heel lang geleden dat ik een 4017 heb gebruikt.

Berichten: 5
Geregistreerd: 09 Aug 2016, 23:24

Re: Hulp efficientie arduino code

Berichtdoor Njick » 10 Aug 2016, 23:24

Koepel schreef:Kun je de pinMode voor die pinnen in setup() zetten ? Dan krijg je dus een for-loop in setup() en in loop().

Je kunt wat gegevens naar de seriele monitor schrijven.
Een Serial.begin(9600) in setup(), en daarna in loop() bijvoorbeeld PWMvalue naar de seriele monitor sturen.

Ik heb zelf geen MSGEQ7, dus ik kan het niet proberen.
Kun je nagaan wat de delays zijn ? Dat staat in de datasheet. Ik vermoed dat er op een paar plaatsen een delay nodig is.

Dat de reset voor de for-loop niet goed werkt, dat begrijp ik niet. Maar het is dan ook heel lang geleden dat ik een 4017 heb gebruikt.


Op een een of andere manier werkt de for loop niet met het outputten van alle verschillende frequenties.
De ''manual'' manier die ik verbeterd hebt werkt nu wel prima, dus ik hou het daar bij! :D
Toch bedankt voor alle handige tricks en tips, heb er zeker wat van geleerd!

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: oejememumilug en 102 gasten