Marek-Vlaky.eu Ovládanie a automatizácia Pulzné ovládanie jazdy analógového vlaku po druhé

Pulzné ovládanie jazdy analógového vlaku po druhé

Pulzné ovládanie jazdy analógového vlaku po druhé post thumbnail image

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š

Značky:,

Podobné články