Slot car bench tool and controller (2 in 1)
Bench tool used for checking your slot car using PWM that can be used also as a controller for a ghost car
Devices & Components
1
Arduino Nano
1
SSD1306 I2C OLED 128x64
1
TIP120 Transistor
2
Resistor 10k
2
Diode 1N4001
1
LM7805 Voltage regulator
1
Push Button
1
Resistor 150 Ohm
1
rotary encoder
Hardware & Tools
1
Soldering kit
Software & Tools
Arduino IDE
Project description
Code
DC motor tip120 encoder
cpp
.
1//ver 20240609 2 3#define ENCODER_OPTIMIZE_INTERRUPTS 4#include <Wire.h> 5#include <Encoder.h> 6#include <OneButton.h> 7#include <Adafruit_GFX.h> 8#include <Adafruit_SSD1306.h> 9/* 10 Definisco le dimensioni del display, serviranno per creare l'istanza del display 11 e magari riutilizzarle nel codice qualora dovessero servirmi queste informazioni 12*/ 13#define SCREEN_WIDTH 128 // OLED display width, in pixels 14#define SCREEN_HEIGHT 64 // OLED display height, in pixels 15 16#define motore 11 // pin collegato a B di TIP120 - Tper 490hz 17#define butEncoder_PIN 4 // Definisci il pin del pulsante dell' encoder 18#define butEngine_PIN 5 // Definisci il pin del pulsante On/OFF del motore 19 20// Creo istanza del display 21Adafruit_SSD1306 disp(SCREEN_WIDTH, SCREEN_HEIGHT); 22// Creo istanza butEngine e butEncoder 23OneButton butEngine(butEngine_PIN, true, true); 24OneButton butEncoder(butEncoder_PIN, true, true); 25// Creo istanza encoder 26Encoder enc1(2,3);//2 DT Verde; 3 CLK giallo; creo l'oggetto enc1 e gli associo i pin - si consiglia di montare le resistenze di pullup fisiche (10k) 27// Variabili per Encoder e SW 28unsigned long lastEncoderTime = 0; 29unsigned long lastSWTime = 0; 30unsigned long debounceDelay = 110; // Tempo di debounce in millisecondi 31bool butEncoderState=true; 32int VM=150; 33float V1=0; 34int Vmin=65;//potenza minima sotto la quale fermare il motore per evitare che le inerzie lo rovinino (valore compreso tra 0 e 255) 35long pos =0; 36long oldpos =0; 37int incr = 25; 38int incrMAX= 25; 39int incrMIN= 3; 40//Variabili per button e engine 41bool engine = false; 42String testo; 43String engineState="OFF"; 44 45void setup() { 46 //Provo ad inizializzare il display all'indirizzo 0x3C (il tuo potrebbe essere diverso) 47 if (!disp.begin( SSD1306_SWITCHCAPVCC, 0x3C)) { 48 /* 49 Se non sono riuscito ad inizializzare il display 50 creo un loop infinito ed impedisco al programma di andare avanti 51 */ 52 while (true); 53 } 54 disp.clearDisplay(); // Pulisco il buffer del display 55 disp.setTextColor( WHITE);//Setto il colore del testo a "bianco" 56 disp.setTextSize(1); //Setto dimensione del testo 57 disp.setCursor(0, SCREEN_HEIGHT / 2); //Sposto il cursore a metà altezza del display 58 disp.print("Startup in progress"); 59 disp.display(); // Applico la pulizia al display 60 pinMode(butEncoder_PIN, INPUT_PULLUP); // Configura il pin SW come input con pull-up 61 pinMode(motore,OUTPUT); //Configura il pin PWM per la base del TIP 120 62 pinMode(butEngine_PIN, INPUT_PULLUP); // Configura il pin del pulsante con resistenza di pull-up interna 63 butEngine.attachClick(toggleEngine); // Assegna la funzione toggleEngine all'evento click del pulsante 64 butEncoder.attachClick(toggleEncoder); 65 66 delay (1000); 67} 68 69// Funzione per gestire il click del pulsante 70void toggleEngine() { 71 engine = !engine; // Cambia lo stato dell'engine 72} 73// Funzione per gestire il click dell' pulsante encoder 74void toggleEncoder() { 75 butEncoderState=!butEncoderState; 76 incr = (butEncoderState == false) ? incrMIN : incrMAX; //se SWState è LOW, allora incr sarà assegnato il valore di incrMIN, altrimenti incr sarà assegnato il valore di incrMAX. 77} 78// Funzione per gestire la potenza del motore 79void startEngine() { 80 analogWrite(motore,V1); 81 engineState="ON"; 82} 83// Funzione per gestire fermare il motore 84void stopEngine() { 85 analogWrite(motore,0); 86 engineState="OFF"; 87} 88void stampaTesto() { 89 //Ripulisco il buffer 90 disp.clearDisplay(); 91 //Setto il colore del testo a "bianco" 92 disp.setTextColor( WHITE); 93 //Setto dimensione del testo 94 disp.setTextSize(2); 95 disp.setCursor(0, 0); 96 disp.print("Eng: "); 97 disp.print(engineState); 98 99 disp.setTextSize(1); 100 disp.setCursor(0, SCREEN_HEIGHT / 8*3); 101 disp.print("DuC: "); 102 disp.print(int(V1/255*100));disp.print("% "); 103 disp.print(float(12*V1/255));disp.print("V "); 104 disp.print(int(V1)); 105 disp.setCursor(0, SCREEN_HEIGHT / 8*6); 106 disp.setTextSize(1); 107 disp.print("Step: "); 108 disp.println(testo); 109 disp.display(); 110 111 //Sposto il cursore a metà altezza del display 112 //disp.setCursor(0, SCREEN_HEIGHT / 2); 113 //Stampo una scritta 114 //display.println(" A + B = C "); 115 //La mando in stampa 116 //display.display(); 117} 118 119void loop() { 120 butEngine.tick(); // Chiama il metodo tick per controllare lo stato del pulsante 121 butEncoder.tick(); 122 // Usa la struttura switch-case per gestire lo stato del motore 123 switch (engine) { 124 case false: 125 stopEngine(); 126 break; 127 case true: 128 startEngine(); 129 break; 130 } 131 if ((millis() - lastEncoderTime) > debounceDelay) { 132 pos = enc1.read(); //legge la posizione assoluta dell'encoder. 133 lastEncoderTime=millis(); 134 } 135 136 if (pos > oldpos) { // quando pos è > di oldpos Aumenta V1 137 V1=V1+incr; if (V1>255){V1=255;};if (V1<Vmin){V1=Vmin;} 138 oldpos = pos; //salvo il valore corrente nella vecchia posizione in attesa del nuovo 139 } 140 if (pos < oldpos) { // quando pos è < di oldpos diminuisce V1 141 V1=V1-incr; if (V1<Vmin){V1=0;} 142 oldpos = pos; //salvo il valore corrente nella vecchia posizione in attesa del nuovo 143 } 144 145 //analogWrite(motore,V1); la sposto nella funzione startEngin() 146 testo = (incr == incrMIN) ? "low" : "HIGH"; 147 stampaTesto(); 148}
Documentation
Elettric schema
Fritzing schema with components
Arduino alimentatore pwm motore encoder_schem.jpg

Comments
Only logged in users can leave comments