reel2reel teller

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

Re: reel2reel teller

Berichtdoor Koepel » 15 Dec 2016, 06:58

Ik begrijp nog steeds niet wat je met andere variabelen zou willen.
Zoals dit:
Code: Alles selecteren
if (newPosition != oldPosition) {    //  oldPosition is de vorige puls
    oldPosition = newPosition;


De ShowHHMMSS() functie zie ik als een aanhangsel, als een departement zeg maar. Het hangt er zomaar bij. Het aantal pulsen kun je er naar toe gooien, en wat die functie er mee doet dat is niet belangrijk voor de structuur van de code in de loop().

Ik zal een voorbeeld geven hoe je de functie gebruikt, daarvoor verander ik je sketch. Ik heb het niet getest, dus er kan nog een foutje in zitten. Het aantal uren kan nu tot 99, er was namelijk geen reden om het af te kappen op 24.

De basis van de sketch vormt de variabele "positie". Dat zijn het aantal pulsen dat de library geeft. Het is nu een lokale variabele binnen de loop(), maar misschien dat het later toch een globale variabele gemaakt moet worden.

Het hart van de sketch is de loop() en de hele loop() bestaat uit het opvragen en afdrukken. Op nul zetten zit er nu nog niet bij, omdat ik nog niet weet hoe je dat wilt gaan doen.

Ik heb in de functie de 'pulses' negatief gelaten (als die negatief was), en de 'totalseconds' altijd een positief getal gemaakt. Dan blijft de 'pulses' origineel, omdat die misschien later voor iets anders binnen de functie nodig zou kunnen zijn.

Het formaat van de uitvoer had je niet gespecificeerd, dus ik heb zelf maar wat gekozen. Dat kan natuurlijk anders. Je kunt het min-teken achteraan zetten, of de uren weglaten als ze nul zijn.

Code: Alles selecteren
// Tellercode
// ----------
// Met Encoder Library
//   http://www.pjrc.com/teensy/td_libs_Encoder.html
//


#include <Encoder.h>

Encoder myEnc(2, 3);   // interruptpinnen arduino uno


void setup() {
  Serial.begin(9600);
  Serial.println("TellerTest:");

  myEnc.write(0);    // startpunt van telling = 0
}


void loop() {
  long positie = myEnc.read();   // De huidige positie van de band in pulsen.

  ShowHHMMSS(positie);      // druk het af

  // Een delay, om twee keer per seconde de positie af the drukken.
  // Deze delay zou later kunnen verdwijnen, wanneer millis()
  // gebruikt wordt om het display te updaten.
  delay(500);   
}


// ---------------------------------------------
// functie: ShowHHMMSS()
// Drukt de pulses af in uren, minuten en seconden.
// Formaat: (-)HH:MM:SS
//   Plus 1 minuut wordt: 00:01:00
//   Minus 6 seconden wordt: -00:00:06
// ---------------------------------------------
void ShowHHMMSS(long pulses) {
  long totalseconds = pulses / 2;  // Wat is de conversie factor van pulsen naar seconden ?

  if( totalseconds < 0) {
    Serial.print('-');
    totalseconds = -totalseconds;   // maak het een positief getal.
  }

  // Op dit moment is totalseconds altijd positief.
  // Een eventueel min-teken is al afgedrukt.

  // splits het totaal aantal seconden naar uren, minuten en seconden.
  int hours = int( (totalseconds / (60L * 60L)) % 100L);   // tot maximaal 99 uren
  int minutes = int( (totalseconds / 60L) % 60L);
  int seconds = int( totalseconds % 60L);

  // ----------------------- uren ------
  if (hours < 10) {
    Serial.print('0');
  }
  Serial.print(hours);
  Serial.print(':');
 
  // ----------------------- minuten ------
  if (minutes < 10) {
    Serial.print('0');
  }
  Serial.print(minutes);
  Serial.print(':');
 
  // ----------------------- seconden ------
  if (seconds < 10) {
    Serial.print('0');
  }
  Serial.println(seconds);
}

Advertisement

Berichten: 12
Geregistreerd: 05 Dec 2016, 15:07

Re: reel2reel teller

Berichtdoor dyk » 16 Dec 2016, 00:21

mmkay, makes sense wat die variabelen betreft. De library geeft de pulsen.
En zoals het er nu staat staat ShowHHMMSS los van de loop. En ik maar al die tijd denken dat al die variabelen bovenin gedeclareerd moeten worden, dat maakte het verwarrend in andere sketches , snap nu dat ik dat anders moet gebruiken.

Voor de nulknop had ik de resetknop van de arduino in gedachten en zoals de sketch nu is kan dat.
De zero -return knop, handig voor het ff/rew spoelen, die op de machine zit is een aan/uit knop en die fysieke knop wil ik weer gebruiken, dit wil ik absoluut in de sketch zetten. ff Kijken hoe ik een nulpunt krijg wat ik kan gebruiken.
Als ik de reset knop vd arduino gebruik veranderd er niks aan de status vd schakelaar dus daar hoef ik geen rekening mee te houden.
Er zit ook nog een 3-standen schakelaar op voor de bandsnelheid en die zou ik door het aantal pulsen te verlagen in de sketch ook nog kunnen gebruiken, maar dat is voor nu nog niet zo belangrijk, eerst die zero return knop maar ‘ns aan de praat krijgen.

Ook in de sketch: Voor de display wil ik een 6 cijferig 7-segment led gebruiken met een max7219 met serïele ingang, die maak ik mooi met een printje op de plaats vd oude teller en de arduino hang ik zonder dat ik een hele bos draden nodig heb verderop in de kast. De sketch aanpassen aan de display dus. Extra nul voor de uren is niet nodig omdat een reel tape max 4,5 uur duurt op de laagste bandsnelheid die ik eigenlijk nooit gebruik.
Code: Alles selecteren
if (hours < 10)
Serial.print('0');
}

kan er uit dus. Hou ik mooi een segment over voor de min, dus: -0:00:00 of -0.00.00 ligt aan de display, moet nog iets bestellen in een mooi klein formaat.
Ik heb de sketch getest en hij werkt, heeft nu voorlopig werknaam tellertest_koepel (humble as I am)

Berichten: 12
Geregistreerd: 05 Dec 2016, 15:07

Re: reel2reel teller

Berichtdoor dyk » 16 Dec 2016, 01:03

Ben nog even aan het stoeien geweest met de sketch en heb de zero-return knop erbij gemaakt.
Heb daarvoor de button voorbeeldsketch uit de arduino ide wat aangepast en ingevoegd.

Code: Alles selecteren
 // Tellercode
// ----------
// Met Encoder Library
//   http://www.pjrc.com/teensy/td_libs_Encoder.html
//


#include <Encoder.h>

Encoder myEnc(2, 3);   // interruptpinnen arduino uno

const int buttonPin = 6;     // nummer van de zero return schakelaar
const int relaisPin =  13;   // nummer relaispin
int buttonState = 0;         // variabele voor de status van de schakelaar


void setup() {


  pinMode(relaisPin, OUTPUT);
  pinMode(buttonPin, INPUT);

  Serial.begin(9600);
  Serial.println("TellerTest:");

  myEnc.write(0);    // startpunt van telling = 0
}


void loop() {
  long positie = myEnc.read();   // De huidige positie van de band in pulsen.

  ShowHHMMSS(positie);      // druk het af

  // Een delay, om twee keer per seconde de positie af the drukken.
  // Deze delay zou later kunnen verdwijnen, wanneer millis()
  // gebruikt wordt om het display te updaten.
  delay(500);
}
// ---------------------------------------------
// functie: ShowHHMMSS()
// Drukt de pulses af in uren, minuten en seconden.
// Formaat: (-)HH:MM:SS
//   Plus 1 minuut wordt: 00:01:00
//   Minus 6 seconden wordt: -00:00:06
// ---------------------------------------------
void ShowHHMMSS(long pulses) {
  long totalseconds = pulses / 64;  // Wat is de conversie factor van pulsen naar seconden ?

  if ( totalseconds < 0) {
    Serial.print('-');
    totalseconds = -totalseconds;   // maak het een positief getal.
  }

  // Op dit moment is totalseconds altijd positief.
  // Een eventueel min-teken is al afgedrukt.

  // splits het totaal aantal seconden naar uren, minuten en seconden.
  int hours = int( (totalseconds / (60L * 60L)) % 100L);   // tot maximaal 99 uren
  int minutes = int( (totalseconds / 60L) % 60L);
  int seconds = int( totalseconds % 60L);

  // ----------------------- uren ------
  //if (hours < 10) {
  //  Serial.print('0');
  // }
  Serial.print(hours);
  Serial.print(':');

  // ----------------------- minuten ------
  if (minutes < 10) {
    Serial.print('0');
  }
  Serial.print(minutes);
  Serial.print(':');

  // ----------------------- seconden ------
  if (seconds < 10) {
    Serial.print('0');
  }
  Serial.println(seconds);

 buttonState = digitalRead(buttonPin);                                         // kijk naar de status van de schakelaar
  if (hours == 0 && minutes == 0 && seconds == 0 && buttonState == HIGH) {     // als aan alle voorwaarden voldaan is,
    digitalWrite(relaisPin, HIGH);                                             // schakel het relais in
  }
  else {
    digitalWrite(relaisPin, LOW);                                              // schakel het relais weer uit
  }
}

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

Re: reel2reel teller

Berichtdoor Koepel » 16 Dec 2016, 03:42

Mijn idee was om de pulsen als basis te nemen, en nu ga je kijken of de uren, minuten en seconden nul zijn. Die "ShowHHMMSS()" functie is echt alleen maar om de pulsen om te zetten naar HH:MM:SS. Daarom benadrukte ik zo sterk dat die functie er maar een beetje bij hangt. Nu zitten we met twee gedachten in dezelfde sketch :o

Tussen de "loop()" en functie "ShowHHMMSS()" had ik een paar lege regels. Dat staat veel leuker ;)
Code: Alles selecteren
  ...
  // gebruikt wordt om het display te updaten.
  delay(500);
}


// ---------------------------------------------
// functie: ShowHHMMSS()
...


Wat bedoel je met zero return ?
Wil je de teller op nul zetten of het relais activeren totdat de band bij nul is ? En wat als hij er voorbij schiet en de seconden net niet nul zijn. De loop() is tenslotte vertraagd met 500ms, ook al is dat maar tijdelijk omdat het met millis() beter zou zijn.

Berichten: 12
Geregistreerd: 05 Dec 2016, 15:07

Re: reel2reel teller

Berichtdoor dyk » 16 Dec 2016, 17:47

Hmm dacht even quick &dirty een zero- return in te bouwen. In principe werkt het , heb ik even getest maar je hebt gelijk, als de band doorschiet omdat hij wat nullen mist doet ie niks, had ik nog niet bij stilgestaan.
En nog de tijd gebruikt ipv de pulsen.. Een delay erbij lijkt me niet zo handig in dit geval, of wel ?? De encodersignalen zitten per slot van rekening op de interruptpinnen van de arduino…………. Pfff denk toch maar millis() dus.
Ik had al even geprobeerd om niét de ShowHHMMSS te gebruiken maar de pulsen in de loop() maar ben er nog niet helemaal uit.

N.B. Met de zero-return of zero stop knop bedoel ik, op het moment dat die aanstaat en je gaat de band spoelen, rewind of fast forward (rew & ff) stopt de band bij nul. De reset knop is om de teller op nul te zetten, niet zo onzinnig om daar de resetpin van de µcontroller voor te gebruiken omdat ik toch geen geheugen functie oid hoef/wil, toch?

Berichten: 12
Geregistreerd: 05 Dec 2016, 15:07

Re: reel2reel teller

Berichtdoor dyk » 16 Dec 2016, 18:40

Heb de sketch veranderd en nu de pulsen gebruikt om de band te laten stoppen, maar nog geen millis() . Tot nu toe nog steeds zonder, misschien tenenkrommend voor de pro’s maar ik heb de sketch getest en hij werkt.

Volgende stap: millis() inbouwen

Code: Alles selecteren
 // Tellercode
// ----------
// Met Encoder Library
//   http://www.pjrc.com/teensy/td_libs_Encoder.html
//


#include <Encoder.h>

Encoder myEnc(2, 3);   // interruptpinnen arduino uno

const int buttonPin = 6;     // nummer van de zero return schakelaar
const int relaisPin =  13;   // nummer relaispin
int buttonState = 0;         // variabele voor de status van de schakelaar


void setup() {


  pinMode(relaisPin, OUTPUT);
  pinMode(buttonPin, INPUT);

  Serial.begin(9600);
  Serial.println("TellerTest:");

  myEnc.write(0);    // startpunt van telling = 0
}

void loop() {
  long positie = myEnc.read();   // De huidige positie van de band in pulsen.

  ShowHHMMSS(positie);      // druk het af

  // Een delay, om twee keer per seconde de positie af the drukken.
  // Deze delay zou later kunnen verdwijnen, wanneer millis()
  // gebruikt wordt om het display te updaten.
  delay(500);
 
  // de band stopt bij nul als buttonState == HIGH maar door de snelheid van de
  // band is het beter het wat eerder te stoppen, vandaar "positie 100"
  // dit getal 100 is later proefondervindelijk te veranderen, btw de oude analoge
  // teller schiet de nul altijd voorbij
 
  buttonState = digitalRead(buttonPin);                            // kijk naar de status van de schakelaar
  if (positie > -100 && positie < 100 && buttonState == HIGH) {    // als aan alle voorwaarden voldaan is,
    digitalWrite(relaisPin, HIGH);                                 // schakel het relais in
  }
  else {
    digitalWrite(relaisPin, LOW);                                  // schakel het relais weer uit
  }
}


// ---------------------------------------------
// functie: ShowHHMMSS()
// Drukt de pulses af in uren, minuten en seconden.
// Formaat: (-)HH:MM:SS
//   Plus 1 minuut wordt: 00:01:00
//   Minus 6 seconden wordt: -00:00:06
// ---------------------------------------------

void ShowHHMMSS(long pulses) {
  long totalseconds = pulses / 64;  // Wat is de conversie factor van pulsen naar seconden ?

  if ( totalseconds < 0) {
    Serial.print('-');
    totalseconds = -totalseconds;   // maak het een positief getal.
  }

  // Op dit moment is totalseconds altijd positief.
  // Een eventueel min-teken is al afgedrukt.

  // splits het totaal aantal seconden naar uren, minuten en seconden.
  int hours = int( (totalseconds / (60L * 60L)) % 100L);   // tot maximaal 99 uren
  int minutes = int( (totalseconds / 60L) % 60L);
  int seconds = int( totalseconds % 60L);

  // ----------------------- uren ------
  //if (hours < 10) {
  //  Serial.print('0');
  // }
  Serial.print(hours);
  Serial.print(':');

  // ----------------------- minuten ------
  if (minutes < 10) {
    Serial.print('0');
  }
  Serial.print(minutes);
  Serial.print(':');

  // ----------------------- seconden ------
  if (seconds < 10) {
    Serial.print('0');
  }
  Serial.println(seconds);


}

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

Re: reel2reel teller

Berichtdoor Koepel » 16 Dec 2016, 19:06

Er ging iets mis, ik had antwoord gegeven, maar het is verdwenen en ook niet bij de concepten te vinden :(

Heb je precies 64 pulses per seconde ? Dat is mooi, dat is heel nauwkeurig dus. Heb je een aparaat dat het kan meten ? Bijvoorbeeld een frequentieteller, oscilloscope of een logic analyzer ?

Die delay(500) in de loop(), die zit er alleen maar om de seriële monitor niet te overladen.
Voor een langzaam LCD display zou ik bijvoorbeeld maar een paar keer per seconde updaten.
Voor een 7-segment LED display, dat hoeft niet vertraagd te worden. Of misschien 30 keer seconde (of nog meer).

Dus nu is die delay(500) een probleem, omdat de encoder dan zijn doel voorbij kan schieten.
Je kunt millis() gebruiken om 2 keer of 4 keer per seconde wat tekst naar de seriële monitor te sturen.

Wil je een knop ingedrukt houden (en die de hele tijd ingedrukt houden) om aan te geven dat de Arduino de band moet stoppen bij nul ? Kun je nog eens uitleggen hoe je het wilt gaan bedienen ?

Ik denk dat het nodig is om te kijken of de band vooruit of achteruit aan het spoelen is. En dan apart bekijken wanneer er gestopt moet worden.
Dit is een window van 200 pulsen: if (positie > -100 && positie < 100 ...
Stel dat het beter is om te stoppen vanaf -50 tot +50. Maar dat die window te klein is en het er voorbij kan schieten.
Wanneer je het apart bekijkt en bijvoorbeeld (positie > -100) doet, dan gaat het altijd goed.

Berichten: 12
Geregistreerd: 05 Dec 2016, 15:07

Re: reel2reel teller

Berichtdoor dyk » 17 Dec 2016, 00:59

Ik heb ong 64 pulsen per seconde, precieze aantal kan ik wel eens meten aan de lichtsluis die er op zit. Had het schema eens bekeken, er staat 12,5 volt op dat ding, de oscilloscoop gebruiken dus. Een paar pulsen meer of minder maakt natuurlijk best veel uit voor de nauwkeurigheid.

Voor de display heb ik ook nog eens een beetje zitten meten en er is wel erg weinig ruimte voor 6 digits dus ik zoek nog naar een mini uitvoering daarvan.
“Je kunt millis() gebruiken om 2 keer of 4 keer per seconde wat tekst naar de seriële monitor te sturen.”
maar als ik een 7-segment display gebruik heb ik eigenlijk die delay(500) helemaal niet nodig als ik het goed begrijp?

De originele knop is een zo’n drukschakelaar met een veer erin , één keer drukken is aan, nog een keer drukken is weer uit, dus zou ik de arduino resetten blijft de schakelaar hoog. Er zit naast de oude display ook nog een drukknop om alles op nul te zetten. Als ik de oude teller er uit haal wil ik die knop ook weer gebruiken door daar een schakelaartje achter te maken en daarop de extra resetpin van de arduino aan te sluiten.

Kijken of dat de band vooruit of achteruit spoelt, hoe doe ik dat?
if ( positie == ++ ) en if (positie == --) of zoiets?
De window van 100 pulsen boven en onder de nul omgerekend 2 x 1,5 seconde is giswerk maar dat duurt het toch wel als hij spoelt voordat hij stilstaat met grote haspels erop. Het blijft een beetje middelen denk ik want ik kan de aandrijving verder niet beïnvloeden.
Op het audiofreaks- en mfb-forum wordt trouwens al regelmatig gerept over het compleet µcontroller gestuurd aandrijven van een tape deck uit de jaren 70, 80 maar ik wil nu alleen een teller. (al denk ik dat dit best te doen is met een arduino )

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

Re: reel2reel teller

Berichtdoor Koepel » 17 Dec 2016, 09:55

Voor een 7-segementen led display is een paar duizend keer per seconde de tijd er naar toe schrijven geen probleem. Ik zie nu echter dat de MAX7219 een seriële chip is. Gelukkig gebruikt die chip de SPI bus en kan tot 10MHz de SPI clock aan.
Dus dat hoeft waarschijnlijk niet vertraagd te worden.
Er zijn trouwens ook mooie OLED schermpjes, die je zonder extra hardware op de Arduino kunt aansluiten.

Om de Arduino op nul te zetten, zou ik niet de reset-pin van de Arduino gebruiken, maar gewoon een digitale ingang.
Als je de reset-pin gebruikt, dan denk ik dat je later in de problemen komt. Ik kan dingen gaan opnoemen: seriële monitor start opnieuw terwijl die handig kan zijn om commando's te geven; je bent alle waarden van de variabelen kwijt; het hoort niet, enzovoorts. Gebruik gewoon een digitale ingang om de teller op nul te zetten.

Het zou mooi zijn als je de richting zou detecteren waarheen de band spoelt. Wiskundig is dat de afgeleide van de 'positie'. Maar dat is misschien voor later.
Als de 'positie' positief is, dan kun je ervan uit gaan dat hij terug spoelt, terug naar nul. En als 'positie' negatief is, dat zal hij wel vooruit spoelen naar nul.
Ik zou het moment detecteren dat de knop wordt ingedrukt (https://www.arduino.cc/en/Tutorial/StateChangeDetection), en dan een variabele zetten die de richting aangeeft.
Dat kost dan iets meer code. Het kan eenvoudiger, maar ik heb liever dat het overzichtelijker is.

Berichten: 12
Geregistreerd: 05 Dec 2016, 15:07

Re: reel2reel teller

Berichtdoor dyk » 18 Dec 2016, 11:17

Oled schermpje zou kunnen, heb er over nagedacht en dat zou best een mooie oplossing zijn, ben bang dat als ik een 6 digit 7-segment gebruik ik de zaag in het frontpaneel moet zetten, kan niks aankomen wat klein genoeg is. Wel wat miniatuurdingen oldstock russian army hier wel cool maar die cijfers zijn maar 3 mm hoog. Die kun je op een paar meter afstand niet meer lezen. Zal eens rondkijken voor een schermpje.

Het is inderdaad verstandiger om gewoon te teller stand op nul te zetten zonder de resetknop van de arduino te gebruiken (dat was achteraf de weg van de minste weerstand, well I’am a novice)
Ik heb een paar regels code toegevoegd:

Code: Alles selecteren
const int resetPin = 7;      //reset knop om teller op nul te zetten
int resetState = 0;          //variabele voor de status van de schakelaar
pinMode(resetPin, INPUT);

void loop() {
resetState = digitalRead(resetPin);    // kijk naar de status van de schakelaar
  if (resetState == HIGH) {              //als de knop ingedrukt is                                       
    myEnc.write (0);                     //zet de pulsteller op nul
    delay(500);
     }
}


Ik heb die link al ff gelezen maar ik zie nog even niet hoe ik code voor moet maken voor de riching die de teller opgaat, ga me daar maar eens even verder in verdiepen.

VorigeVolgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 21 gasten