Paso a Nivel / Railway Crossing

COMPONENTES

 

THE COMPONENTS

     

 

VIDEO

 

THE VIDEO

     
Arriba  

On top

EL CÓDIGO FUENTE

 

THE MAIN CODE

     

 

/* Arduino Nano Pro as
  - WAV sound files player (24 kHz - 8 bit - mono)
  - 1 servo controller - variable speed -
  - 2 alternating common cathode led controller
 Using:
  - 2 current sensing occupancy detectors
  - 1 contact occupancy detector
  - 1 infrared occupancy detector
  - SD card reader
 
  Code by Norber, February 2016

  Freely distributable for private, non commercial, use.

  Connections:
  SD card  GND   to  GND common
  SD card  MISO  to  ARD pin 12
  SD card  SCK   to  ARD pin 13
  SD card  MOSI  to  ARD pin 11
  SD card  CS    to  ARD pin 10
  SD card  5Vcc  to  +5 V cc

  ARD pin 3      to  transistor driven 8 ohms 5V loudspeaker

*/


#include 
#include 
#include 

#define INIT         10
#define DETECTING    20
#define ALARMS_ON    25
#define LOWING_BAR   30
#define BAR_DOWN     40
#define LIFTING_BAR  50
#define ALARMS_OFF   60
#define ERROR_UNKN   90

#define SENSIB       10

#define PIN_K1       8
#define PIN_K2       6
#define PIN_K3       7
#define PIN_IR       2
#define PIN_SERVO    5
#define PIN_LED1     A2
#define PIN_LED2     A3
#define PIN_LED3     A4
#define PIN_LED_PCB  A1
#define PIN_SOUND    3   // Must be 3: OC2B is pin3 - used for playing 8-bit WAV

#define HYSTER       30000  // Interval between alarms and barriers
#define DOWN_POS     2400
#define UP_POS       4000
#define INCR_SV      5
#define VEL_SER      1
#define BLINK_DEL    15  // Led blinking rate

byte sysEst = INIT;
boolean k1St, k2St, k3St, irSt, bellsOn, ledsOn;
volatile int posObj, posNow;
volatile boolean servMoving;

TMRpcm player;

void setup() {
  pinMode(PIN_K1, INPUT_PULLUP);
  pinMode(PIN_K2, INPUT_PULLUP);
  pinMode(PIN_K3, INPUT_PULLUP);
  pinMode(PIN_IR, INPUT_PULLUP);
  pinMode(PIN_LED1, OUTPUT);
  pinMode(PIN_LED2, OUTPUT);
  pinMode(PIN_SERVO, OUTPUT);
  pinMode(10, OUTPUT);
  //Serial.begin(9600);
  if (!SD.begin(10)) {
    // Serial.println("SD card error");
    return;
  }
  //Serial.println("SD card OK");

  cli();
  TCCR0A = 0;
  TCCR0B = 0;
  TCCR0B |= (1 << CS02) | (1 << CS00);      // Set CS00 & CS02 bits for 1024 prescaler on Timer0 - LEDs
  OCR0A = 234;                              // Comp Match every 15 ms  (66.67 Hz)
  TIMSK0 = 0;
  TIMSK0 |= (1 << OCIE0A);                   // Enable Timer0 interrupts for Compare Match A

  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1A |= (1 << WGM11);                    // Turn on Fast PWM mode
  TCCR1B |= (1 << WGM13) | (1 << WGM12);     // Turn on Fast PWM mode
  TCCR1B |= (1 << CS11);                     // Set CS11 bit for 8 prescaler (0.5 µs) on Timer1 - Servos
  ICR1 = 40000;                              // Set PWM fixed frequency (overflow every 20 ms)
  TIMSK1 = 0;
  TIMSK1 |= (1 << OCIE1A) | (1 << TOIE1);    // Enable Timer1 interrupts for Compare Match A & Overflow mode
  sei();                                     // Activar interrupciones

  player.speakerPin = PIN_SOUND;
  player.setVolume(1);
  player.volume(1);
  player.loop(1);
  player.play("Campo3.wav");
  sysEst = DETECTING;
  posNow = UP_POS;
}

boolean readSensors() {
  static int cntr, k1Count, k2Count, k3Count, irCount;
  static boolean result;
  k1Count += digitalRead(PIN_K1);
  k2Count += digitalRead(PIN_K2);
  k3Count += digitalRead(PIN_K3);
  irCount += digitalRead(PIN_IR);
  if (++cntr == SENSIB) {
    if ((k1Count == 0)||(k2Count == 0)||(k3Count)||(irCount == 0)) result = true;
    else result = false;
    cntr = 0;
    k1Count = 0;
    k2Count = 0;
    k3Count = 0;
  }
  return result;
}

void loop() {
  static unsigned int cntr;
  static boolean detection = readSensors();
  switch (sysEst) {
    case DETECTING:
      if (detection) {
        sysEst = ALARMS_ON;
      }
      break;
    case ALARMS_ON:
      if (bellsOn == false) {
        player.play("Bells1.wav");
        bellsOn = true;
        ledsOn = true;
      }
      if (++cntr == HYSTER) {
        sysEst = LOWING_BAR;
        posObj = DOWN_POS;
        servMoving = true;
        cntr = 0;
      }
      break;
    case LOWING_BAR:
      if (servMoving == false) {
        sysEst = BAR_DOWN;
      }
      break;
    case BAR_DOWN:
      if (detection == false) {
        if (++cntr == HYSTER) {
          sysEst = LIFTING_BAR;
          posObj = UP_POS;
          servMoving = true;
          cntr = 0;
        }
      }
      break;
    case LIFTING_BAR:
      if (servMoving == false) {
        sysEst = ALARMS_OFF;
      }
      break;
    case ALARMS_OFF:
      if (++cntr == HYSTER) {
        player.play("Campo3.wav");
        ledsOn = false;
        bellsOn = false;
        PORTC &= 0xF3;
        cntr = 0;
        sysEst = DETECTING;
      }
      break;
    case ERROR_UNKN:
      ledsOn = true;
      break;
  }
}

ISR(TIMER0_COMPA_vect) {                     // Timer0 Compare Match interrupt every 15 ms
  static int cntr;
  if (ledsOn && (++cntr == BLINK_DEL)) {
    if (PINC & 0x04) (PORTC &= 0xF3) |= 0x08;  // Toggle pinA2 and pinA3 alternatively
    else (PORTC &= 0xF3) |= 0x04;
    cntr = 0;
  }
}

ISR(TIMER1_OVF_vect) {                       // Timer1 Overflow interrupt for servo every 20 ms
  static int dif;
  if (servMoving == true) {
    dif = posNow - posObj;
    if (dif < 0) posNow += INCR_SV;
    else if (dif > 0) posNow -= INCR_SV;
    else servMoving = false;
    PORTD |= (1 << 5);                       // Servo is pin5
    OCR1A = posNow;
  }
}

ISR(TIMER1_COMPA_vect) {                     // Timer1 Match Compare A interrupt for servos
  PORTD &= ~(1 << 5);
}

 

ADD-ONS (LIBRERIAS Y OTROS ARCHIVOS)

 

THE ADD-ONS (LIBRARIES AND OTHER FILES)

     

Imprimir