Traffic lights (UK sequence) dengan arduino

Urutan traffic lights standar Inggris mengandung arti sebagai berikut :

  1. Lampu merah,
    Setiap kendaraan wajib berhenti tidak lebih dari garis batas
  2. Lampu merah dan lampu kuning,
    Setiap kendaraan wajib berhenti namun bersiap untuk melanjutkan perjalanan
  3. Lampu hijau,
    Boleh melintasi traffic lights
  4. Lampu kuning,
    Bersiap untuk berhenti di belakang garis batas, tetapi jika sudah melewati garis batas masih di perbolehkan jalan.

Jumlah keseluruhan lampu yang dibutuhkan untuk 4 simpang adalah 12 buah, untuk menghemat jalur pin arduino, maka bisa diterapkan sistem scan yang menggunakan 3 jalur lampu, (untuk merah, kuning, hijau), serta 4 jalur untuk masing-masing posisi trafic led, sehingga untuk 4 simpang diperlukan 7 jalur pengontrolan saja.

skema traffic lights berbasis arduino:

program Urutan traffic lights menggunakan arduino:

#define jumlahTrafficLight    4

byte pinDigit[] = {7, 6, 5, 4};
byte pinRYG[] = {10, 9, 8};

#define lampuMerah    (1 << 2)
#define lampuKuning   (1 << 1)
#define lampuHijau    (1 << 0)

byte hijauSekarang;
byte hijauSelanjutnya;
byte timingTraffic;

struct traffic {
  byte lampu;
  byte lampuSelanjutnya;
  uint32_t waktu;
};

traffic skemaTraffic[] = {
  {lampuHijau  , lampuMerah               , 5000},
  {lampuKuning , lampuMerah               , 1000},
  {lampuMerah  , lampuMerah | lampuKuning , 1000},
};

byte lampuTraffic[jumlahTrafficLight];
byte indexTraffic;
byte indexScan;
uint32_t millisTraffic;
byte jalurDarurat;

void setup() {

  for (byte i = 0; i < jumlahTrafficLight; i++)
  {
    pinMode(pinDigit[i], OUTPUT);
  }
  for (byte i = 0; i < 3; i++)
  {
    pinMode(pinRYG[i], OUTPUT);
  }

  Serial.begin(9600);

  for (byte i = 0 ; i < jumlahTrafficLight; i++)
  {
    lampuTraffic[i] = skemaTraffic[2].lampu;
  }
  hijauSekarang = 0;
  hijauSelanjutnya = 1;

}

void loop() {

  if (millisTraffic < millis())
  {
    lampuTraffic[hijauSekarang] = skemaTraffic[indexTraffic].lampu;
    lampuTraffic[hijauSelanjutnya] = skemaTraffic[indexTraffic].lampuSelanjutnya;
    millisTraffic += skemaTraffic[indexTraffic].waktu;

    indexTraffic++;
    if (indexTraffic == 3)
    {
      indexTraffic = 0;
      hijauSekarang = hijauSelanjutnya;
      hijauSelanjutnya = (hijauSekarang + 1) % jumlahTrafficLight;
    }
  }

  trafficScan();
}

void trafficScan()
{
  digitalWrite(pinDigit[indexScan], HIGH);
  indexScan++;
  indexScan %= jumlahTrafficLight;
  digitalWrite(pinRYG[0], lampuTraffic[indexScan] & lampuMerah);
  digitalWrite(pinRYG[1], lampuTraffic[indexScan] & lampuKuning);
  digitalWrite(pinRYG[2], lampuTraffic[indexScan] & lampuHijau);
  digitalWrite(pinDigit[indexScan], LOW);

}

 

 

SPWM fungsional tanpa tabel-sinusiodal dengan arduino

Sinusoidal Pulse width modulation (SPWM) adalah teknik membangkitkan sinyal sinusiodal dengan metode PWM (pulse width modulation). Sinyal PWM umum di gunakan pada perangkat digital,  sehingga memungkinkan perangkat digital untuk menghasilkan sinyal sinusiodal.

Metode SPWM yang umum digunakan diantaranya :

  1. Segitiga yaitu dengan membandingkan sinyal ramp dengan sinyal sinusiodal dan diperoleh deret duty cycle yang bisa di masukkan dalam tabel.
  2. delta, deret pwm dihasilkan melalui penggambaran slope dalam batas (atas dan bawah) sinyal sinusiodal target.
  3. delta sigma
  4. space vector
  5. direct torque
  6. time proportioning

kehandalan S-PWM di ukur berdasarkan spectrum, karena SPWM adalah sinyal digital yang menyerupai sinyal sinus, maka membutuhkann filter low-pass untuk mengurangi spectrum frekusnsi tinggi dari switching digital.

SPWM juga bisa digunakan sebagai regulator AC untuk keperluan pengontrolan tegangan output.

berikut tata letak pin yang digunakan :

H-bridge dalam skema adalah BTS7960, bisa di ganti dengan modul/rangkaian H-bridge lain

 

sketch program arduino spwm:

#define pinSPWM_A               9
#define pinSPWM_B               10

#define frekuensiOutput         50
#define frekuensiSPWM           1000

volatile byte indexSPWM;
volatile float output;
int limitOutput;

void setup() {
  pinMode(pinSPWM_A, OUTPUT);
  pinMode(pinSPWM_B, OUTPUT);

  Serial.begin(9600);
  Serial.println(F("SPWM fungsional dengan arduino"));
  Serial.println(F("https://www.project.semesin.com"));
  Serial.println();

  TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);

  long cycles = (F_CPU / frekuensiSPWM / 2);
  uint8_t clockSelectBits;

  if      (cycles        < 0xFF) clockSelectBits = _BV(CS10);
  else if ((cycles >>= 3) < 0xFF) clockSelectBits = _BV(CS11);
  else if ((cycles >>= 3) < 0xFF) clockSelectBits = _BV(CS11) | _BV(CS10);
  else if ((cycles >>= 2) < 0xFF) clockSelectBits = _BV(CS12);
  else if ((cycles >>= 2) < 0xFF) clockSelectBits = _BV(CS12) | _BV(CS10);
  else     cycles = 0xFF - 1,    clockSelectBits = _BV(CS12) | _BV(CS10);

  TCCR1B = (1 << WGM13) | clockSelectBits;
  ICR1 = cycles;
  TIMSK1 = _BV(TOIE1);
  OCR1A = 0;
  OCR1B = 0;

  limitOutput = cycles;
}

void loop() {

  output = limitOutput / 2;

}

ISR(TIMER1_OVF_vect)
{
  int duty = 1.0 * sin(2.0 * PI * indexSPWM / (frekuensiSPWM / frekuensiOutput)) * output;

  if (duty >= 0)
  {
    OCR1AL = duty;
    OCR1BL = limitOutput + 1;
  }
  else
  {
    OCR1AL = limitOutput + 1;
    OCR1BL = 0 - duty;
  }

  indexSPWM++;
  indexSPWM %= frekuensiSPWM / frekuensiOutput;
}

output logic analyzer