Pred nejakým časom som uverejnil článok o pulznom ovládači pre analógové koľajiská. Tento ovládač je citlivý, dá sa s ním simulovať plynulý rozbeh či už ľahkého alebo ťažkého vlaku ako aj rovnako plynulé brzdenie. Pri tomto ovládači sa ale prejavila jedna chyba. A to konkrétne osvetlenie lokomotív, ktoré menia svetlo podľa smeru jazdy, totiž svietili vždy všetky led diódy nezávisle od smeru jazdy. Toto bolo spôsobené, ako zistil kamarát a autor nového riešenia Jaro (autor schémy aj programu), mostíkom L293D, ktorý dáva pulzy aj do kladného a aj záporného pólu. Preto prišiel na svet s novým, podobným riešením. Mostík nahradil tranzistorom, ktorý pulzuje iba voči zemi. Kladný pól je teda stálych 12V.
Navyše celý ovládač vylepšil použitím LCD displeja so sériovým prenosom informácií a taktiež rýchlosť vlaku a iné funkcie môžu byť riadené pomocou jediného ovládacieho prvku – digitálneho enkódera, ktorý sa dá na ebay.com k arduinu dokúpiť. Schéma je na konci článku, sem ešte pridávam program:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include “OneButton.h”
#include <Encoder.h>
OneButton button(A2, true);
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Encoder myEnc(A0, A1);
unsigned long previousMillis = 0;
long position = 0;
int smer_Pin = 5 ;
int pwm_Pin = 6;
int oneskorenie_Pin = A7;
int encoder = 0;
int smer = LOW;
int rychlost_1;
int rychlost_2 = 0;
int oneskorenie_1;
int oneskorenie_2;
// obrazky vlakov
byte right1[8] = {
0b00000,
0b00000,
0b11111,
0b01001,
0b01001,
0b01111,
0b00011,
0b00011
};
byte right2[8] = {
0b00000,
0b00000,
0b00000,
0b11111,
0b00000,
0b11111,
0b01101,
0b01101
};
byte right3[8] = {
0b00000,
0b00000,
0b00000,
0b11111,
0b00001,
0b11111,
0b10110,
0b10110
};
byte right4[8] = {
0b00000,
0b11000,
0b11000,
0b11100,
0b00100,
0b11100,
0b11010,
0b11001
};
byte left1[8] = {
0b00000,
0b00011,
0b00011,
0b00111,
0b00100,
0b00111,
0b01011,
0b10011
};
byte left2[8] = {
0b00000,
0b00000,
0b00000,
0b11111,
0b10000,
0b11111,
0b01101,
0b01101
};
byte left3[8] = {
0b00000,
0b00000,
0b00000,
0b11111,
0b00000,
0b11111,
0b10110,
0b10110
};
byte left4[8] = {
0b00000,
0b00000,
0b11111,
0b10010,
0b10010,
0b11110,
0b11000,
0b11000
};
void setup(){
button.attachClick(click);
button.attachDuringLongPress(longPress);
button.attachDoubleClick(doubleclick);
lcd.begin(16, 2);
lcd.clear();
pinMode(smer_Pin, OUTPUT);
pinMode(pwm_Pin, OUTPUT);
lcd.createChar(0, right1);
lcd.createChar(1, right2);
lcd.createChar(2, right3);
lcd.createChar(3, right4);
lcd.createChar(4, left1);
lcd.createChar(5, left2);
lcd.createChar(6, left3);
lcd.createChar(7, left4);
}
void loop(){
button.tick();
oneskorenie_1 = analogRead(oneskorenie_Pin);
long Pos = myEnc.read();
long newPos = Pos/4;
if (newPos != position){
if(newPos < position){
encoder–;
}
if(newPos > position){
encoder++;
}
position = newPos;
}
if (encoder < 0) encoder = 0;
if (encoder > 40) encoder = 40;
rychlost_1 = map(encoder, 0, 40, 0, 255);
oneskorenie_2 = map(oneskorenie_1, 0, 1023, 0, 160);
unsigned long currentMillis = millis();
if (currentMillis – previousMillis > oneskorenie_2){
previousMillis = currentMillis;
if (rychlost_1 < rychlost_2) rychlost_2–;
if (rychlost_1 > rychlost_2) rychlost_2++;
if (rychlost_2 < 0) rychlost_2 = 0;
if (rychlost_2 > 255) rychlost_2 = 255;
}
analogWrite (pwm_Pin, rychlost_2);
if (smer == LOW){
digitalWrite(smer_Pin, LOW);
}
if (smer == HIGH){
digitalWrite(smer_Pin, HIGH);
}
// displej
if(rychlost_1 >= 0 && rychlost_1 < 10){
lcd.setCursor(0, 0);
lcd.print(” “);
lcd.print(rychlost_1);
}
if(rychlost_1 >= 10 && rychlost_1 < 100){
lcd.setCursor(0, 0);
lcd.print(” “);
lcd.print(rychlost_1);
}
if(rychlost_1 >= 100 && rychlost_1 < 1000){
lcd.setCursor(0, 0);
lcd.print(rychlost_1);
}
if(rychlost_2 >= 0 && rychlost_2 < 10){
lcd.setCursor(9, 0);
lcd.print(” “);
lcd.print(rychlost_2);
}
if(rychlost_2 >= 10 && rychlost_2 < 100){
lcd.setCursor(9, 0);
lcd.print(” “);
lcd.print(rychlost_2);
}
if(rychlost_2 >= 100 && rychlost_2 < 1000){
lcd.setCursor(9, 0);
lcd.print(rychlost_2);
}
lcd.setCursor(12, 0);
lcd.print(“/”);
if(oneskorenie_2 >= 0 && oneskorenie_2 < 10){
lcd.setCursor(13, 0);
lcd.print(” “);
lcd.print(oneskorenie_2);
}
if(oneskorenie_2 >= 10 && oneskorenie_2 < 100){
lcd.setCursor(13, 0);
lcd.print(” “);
lcd.print(oneskorenie_2);
}
if(oneskorenie_2 >= 100 && oneskorenie_2 < 1000){
lcd.setCursor(13, 0);
lcd.print(oneskorenie_2);
}
if (smer == LOW){
lcd.setCursor(4,0);
lcd.write(byte(0));
lcd.setCursor(5,0);
lcd.write(byte(1));
lcd.setCursor(6,0);
lcd.write(byte(2));
lcd.setCursor(7,0);
lcd.write(byte(3));
}
if (smer == HIGH){
lcd.setCursor(4,0);
lcd.write(byte(4));
lcd.setCursor(5,0);
lcd.write(byte(5));
lcd.setCursor(6,0);
lcd.write(byte(6));
lcd.setCursor(7,0);
lcd.write(byte(7));
}
}
void click(){
if(rychlost_2 == 0){
smer = !smer;
}
}
void doubleclick(){
encoder = 0;
}
void longPress(){
encoder = 0;
rychlost_2 = 0;
}
V programe je aj jednoduché grafické vykresľovanie smeru jazdy, ktoré sa prepína podľa skutočného smeru jazdy vlaku. Program nebudem veľmi rozpisovať, myslím, že je celkom prehľadný a každý, trochu skúsenejší modelár-elektrotechnik si s tým poradí.
Za skvelé spracovanie schémy a programu ako aj za novú verziu pre ovládač ďakujem kamarátovi a modelárovi Jarovi zo Žarnovice, veľmi si mi pomohol.
Marek Duda, Jaroslav Koteleš