Je hoort het klikken van het "locking" relais
if (!digitalRead(In_1)) { clockwise(1); teller = 2; } if (!digitalRead(In_2)) { clockwise(1); teller = 4; } if (!digitalRead(In_3)) { clockwise(0); teller = 2; } if (!digitalRead(In_4)) { clockwise(0); teller = 4;
Ziet er keurig uit! Valt me op dat de schijf weinig herrie maakt tijdens draaien.
Die van mij maakt inderdaad aardig wat herrie, maar hij 'hang't in het uitgezagen gat, volgens mij is het beter als ik nog wat ondersteuning gaat maken, en het geheel in een bed van kurk leg voor het dempen van het geluid, het is nu een versterker, al dat hout er omheen.
/* ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Arduino DCC Turntable control Original DCC sketch : Arduino DCC solenoid Control Author: Ruud Boer - January 2015 Adapted for turntable control with LDT protocol Dick Koning feb 2017, echter de nummering van de sporen is conform RocRail The DCC signal is optically separated and fed to pin 2 (=Interrupt 0). Schematics: www.mynabay.com Many thanks to www.mynabay.com for publishing their DCC monitor and -decoder code. Basis idee geef korte puls op het locking relais, de draaischijf gaat draaien als de draaischijf 1 positie gedraait heeft, stopt de stroom door de motor automatisch dit genereert een overgang van laag naar hoog op de motor sense pin Gebruik dit event om te bepalen hoeveeel afslagen er gedraaid is en genereer eventueel een nieuwe puls versie DCC_draai_8 :inbouwen DCC stuurelementen, eenvoudige koppeling tussen DCC en draaischijf gemaakt :onderstening van commando'ga naar track nr , + 1 track, -1 track nummering aansluitpinnen veranderd TODO kijken of individuele routines werken ( dcc monitor } TODO break statement tijdens daai, ompolen sporen routine //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/#define aan 0 // tbv relais ingangen zijn geinverteerd #define uit 1#define richting1 3 // Arduino Digital I/O pin number tbv relais sturing#define richting2 4 // 2 single relais altijd gelijkop bewegen bepalen de draairichting#define lock 5 // relais wat de interne "lock" van de draaischijf aanstuurt //#define Relay_4 6#define In_1 8 // Arduino Digital I/O pin number tbv schakelaars#define In_2 9#define In_3 10#define In_4 11#define cSense 12 // curent sense motoraandrijving#include <DCC_Decoder.h> // Mynabay DCC library#define kDCC_INTERRUPT 0// Globale variabelenbool pulsBusy = false; // pulsBusy is de variable die aangeeft dat het interne draaischijf locking relais geactiveerd isunsigned long pulsTimer = 0; // pulsTimer is de teller die meeloopt met de duur van de relais pulsunsigned long pulsDuur = 2000; // pulsDuur geeft aan hoelang de puls default duurt Moet iets korter zijn dan de tijd die nodig is voor 1 stapint teller = 0; // teller is het aantal afslagen dat de scijf moet draaienint track = 0; // actuele afslag waar de draaischijf zich bevindtint target = 0; // doel waarnaar naar toe gedraaid moet wordenbool railrelais = 0; // toekomstig ompool relais//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FILL INconst byte maxaccessories = 5; //The number of "LDT command" adressen you want to control with this Arduino//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////typedef struct{ int address; // Address to respond to byte output; // State of accessory: 1=on, 0=off rood /groen in wissel commando int track; // turntable tracknumber int track2; // turntable track number boolean finished; // finished : 0=busy 1= ready for next command boolean activate; // start verwerking commando unsigned long offMilli; // for internal use unsigned long durationMilli; // for internal use "busy periode"}DCCAccessoryAddress;DCCAccessoryAddress accessory[maxaccessories];//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// DCC packet handler//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data){ // Convert NMRA packet address format to human address address -= 1; address *= 4; address += 1; address += (data & 0x06) >> 1; boolean enable = (data & 0x01) ? 1 : 0; for (int i = 0; i < maxaccessories; i++) { if ( address == accessory[i].address ) { accessory[i].activate = 1; if ( enable ) { accessory[i].output = 1; } else { accessory[i].output = 0; } } }} // END BasicAccDecoderPacket_Handler//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Initialization: COPY - PASTE the structure as many times as you have commands and fill in the values you want.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void ConfigureDecoderFunctions() // The amount of accessories must be same as in line 52 above!{ accessory[0].address = 226; // basisadres LDT =225, eerste commando accessory[0].track = 0; accessory[0].track2 = 0; accessory[0].finished = 1; // Do not change this value accessory[0].activate = 0; // Do not change this value accessory[0].output = 0; // Do not change this value accessory[0].durationMilli = 500; accessory[1].address = 228; accessory[1].track = 0; accessory[1].track2 = 0; accessory[1].finished = 1; // Do not change this value accessory[1].activate = 0; // Do not change this value accessory[1].output = 0; // Do not change this value accessory[1].durationMilli = 500; accessory[2].address = 229; accessory[2].track = 1; accessory[2].track2 = 2; accessory[2].finished = 1; // Do not change this value accessory[2].activate = 0; // Do not change this value accessory[2].output = 0; // Do not change this value accessory[2].durationMilli = 500; accessory[3].address = 230; // basisadres LDT =225, eerste commando accessory[3].track = 3; accessory[3].track2 = 4; accessory[3].finished = 1; // Do not change this value accessory[3].activate = 0; // Do not change this value accessory[3].output = 0; // Do not change this value accessory[3].durationMilli = 500; accessory[4].address = 231; accessory[4].track = 5; accessory[4].track2 = 6; accessory[4].finished = 1; // Do not change this value accessory[4].activate = 0; // Do not change this value accessory[4].output = 0; // Do not change this value accessory[4].durationMilli = 500;} // END ConfigureDecoderFunctions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void setup(){ DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true); ConfigureDecoderFunctions(); DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); //-------( Initialize Pins so relays are inactive at reset)---- digitalWrite(richting1, uit); digitalWrite(richting2, uit); digitalWrite(lock, uit); //digitalWrite(Relay_4, uit); //---( THEN set pins as outputs )---- pinMode(richting1, OUTPUT); pinMode(richting2, OUTPUT); pinMode(lock, OUTPUT); //pinMode(Relay_4, OUTPUT); delay(1000); //Check that all relays are inactive at Reset pinMode(In_1, INPUT_PULLUP); pinMode(In_2, INPUT_PULLUP); pinMode(In_3, INPUT_PULLUP); pinMode(In_4, INPUT_PULLUP); pinMode(cSense, INPUT); pinMode(2, INPUT_PULLUP); //Interrupt 0 with internal pull up resistor (can get rid of external 10k) pinMode(13, OUTPUT); digitalWrite(13, LOW); //turn off Arduino led at startup Serial.begin(38400); target = 0; track = 0; teller = 0;} //--(end setup )---//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Main loop//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void loop(){ // target gewenste afslag // track actuele afslag // teller aantal slagen // clockwise(1) : clockwise clockwise(0) : counter clockwise leesDCC(); // genereert een gewenst afslag nummer pushButton(); // genereert een gewenst afslag nummer if (target > track) { Serial.println ("Target > Track"); teller = target - track; if (teller <= 24) { clockwise(0); Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track); while (teller > 0) { // niet definitief gebruiken, blokkeert alles draai(0); } } else { teller = 48 - teller ; clockwise(1); Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track); while (teller > 0) { // niet definitief gebruiken, blokkeert alles draai(1); } } } if (track > target) { Serial.println ("Target < Track"); teller = track - target; if (teller <= 24) { clockwise(1); Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track); while (teller > 0) { // niet definitief gebruiken, blokkeert alles draai(1); } } else { teller = 48 - teller ; clockwise(0); Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track); while (teller > 0) { // niet definitief gebruiken, blokkeert alles draai(0); } } }}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Aansturing van de draaischijf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void draai(bool richting){ // pulsBusy is de variable die aangeeft dat het interne draaischijf locking relais geactiveerd is // pulsTimer is de teller die meeloopt met de duur van de relais puls // pulsDuur geeft aan hoelang de puls default duurt // teller is het aantal afslagen dat de schijf moet draaien // richting is de variabele die aangeeft welke kant de draai opgaat if (!pulsBusy) { pulsTimer = millis() + pulsDuur; pulsBusy = true; digitalWrite(lock, aan); delay(10); // probeersel } else { if ( millis() > pulsTimer) { digitalWrite(lock, uit); // de default pulsperiode is voorbij if (digitalRead(cSense)) { //cSense is hoog : er loopt geen stroom door de motor Hier moet je mischien nog iets van een debounce in zetten teller = teller - 1; pulsBusy = false; if (richting) { // richting 1=clockwise 0=counterclockwise track = track - 1; if (track < 0) track = track + 48; Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track); // zet hier statement voor ompolen rail relais //if (track == 12 || track == 36) railrelais = !railrelais; } else { track = track + 1; if (track >= 48) track = track - 48; Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track); } } } } if (!digitalRead(cSense)) { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); }}//--(end draairoutine )---//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// DCCLoop//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void leesDCC(){ static int addr = 0; // Static variable assignment alleen bij startup. Waarde persisteert als de functie verlaten wordt DCC.loop(); // Loop DCC library if ( ++addr >= maxaccessories ) addr = 0; // Bump to next address to activate if (accessory[addr].finished && accessory[addr].activate) //event wordt 1 maal getriggerd daarna verplichte pauze { accessory[addr].finished = 0; accessory[addr].offMilli = millis() + accessory[addr].durationMilli; if (accessory[addr].output == 1) { switch (accessory[addr].address) { case 226: // halve draai target = track + 24; if (target >= 48) target = target - 48; break; case 228: // 1 step clockwise target = track - 1; if (target < 0) target = target + 48; break; default: target = (accessory[addr].track); break; } Serial.print ("Ga naar target track (rood) "); Serial.println(target); } else { switch (accessory[addr].address) { case 226: // halve draai target = track - 24; if (target < 0) target = target + 48; break; case 228: // 1 step counter clockwise target = track + 1 ; if (target >= 48) target = target - 48; break; default: target = (accessory[addr].track2); break; } Serial.print ("Ga naar target track (groen) "); Serial.println(target); } } if ((!accessory[addr].finished) && (millis() > accessory[addr].offMilli)) // blokkade want commando herhaalt zich zelf { accessory[addr].finished = 1; accessory[addr].activate = 0; }}void clockwise(bool on){ Serial.print("Set rotatie: "); if (on) { digitalWrite(richting1, aan); digitalWrite(richting2, aan); Serial.println("Clockwise "); } else { digitalWrite(richting1, uit); digitalWrite(richting2, uit); Serial.println("Counter Clockwise"); } delay(10);}void pushButton(){ // invoer dmv druk toetsen 0 = ingedrukt // Serial.println("Lees PushButton"); if (!digitalRead(In_1)) { target = track + 2; if (target >= 48) target = target - 48; } if (!digitalRead(In_2)) { target = track + 4; if (target >= 48) target = target - 48; } if (!digitalRead(In_3)) { target = track - 2; if (target < 0) target = target + 48; } if (!digitalRead(In_4)) { target = track - 4; if (target < 0) target = target + 48; }}
Serial.print("Teller :"); Serial.print(teller); Serial.print(" Target : "); Serial.print(target); Serial.print(" Track : "); Serial.println(track);
... En die debug, gewoon laten zitten en een display eraan / erbij.Op display dan track / target / richting / draaiend ja nee laten zien.
accessory[3].address = 230; // basisadres LDT =225, eerste commando accessory[3].track = 3; accessory[3].track2 = 4;
algoritme klopt wel, staat er wat ongelukkig
Ik ben niet zo vertrouwd met procedure parameters
void DebugData(int Counter, int TrackTarget, int TrackActual){ Serial.print("Teller :"); Serial.print(Counter); Serial.print(" Target : "); Serial.print(TrackTarget); Serial.print(" Track : "); Serial.println(TrackActual);}