Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Slim Verkeerslichtsysteem met Real-Time Data

Onderdelen en benodigdheden

Arduino Yun1
Arduino UNO (of een ander Arduino-bord)1
Ultrasone sensor HC-SR041
DS3231 RTC (Real Time Clock)1
LED's (1× rood, 1× geel, 1× groen)3
Weerstand 330 Ω3
433 MHz modules (1× zender, 1× ontvanger)1 set
Android-apparaat1
SD-kaart1
AllThingsTalk IOTOPIA Rapid Development kit1
Draadjes (jumper wires)1 set

Apps en online diensten

  • Arduino IDE
  • Android Studio
  • MySQL-database hosting (bijv. freemysqlhosting.net)

Over dit project

Inleiding

Verkeersdrukte is een bron van frustratie en neemt toe. Wat als slimme verkeerslichten dat kunnen veranderen? We hebben een Verkeerslicht-Informatiesysteem ontwikkeld dat de automobilist informeert over de optimale snelheid om het groene licht te halen zonder de maximumsnelheid te overschrijden. Als wachten onvermijdelijk is, toont het systeem hoelang het nog duurt voordat het licht op groen springt.

Slim Verkeerslichtsysteem met Real-Time Data

Een verkeerslicht stuurt data over de resterende groene of rode tijd naar een online database. Een smartphone-app haalt deze data op en berekent de aanbevolen snelheid. Bij een rode fase wordt een afteltimer getoond.

Voorbeeld

Je rijdt in een 70 km/h-zone, 500 meter voor een rood licht dat over 30 seconden groen wordt. Het systeem adviseert om 60 km/h te rijden om het groene licht te halen.

Slim Verkeerslichtsysteem met Real-Time Data

Projectdemonstratie

Hoe we het gebouwd hebben

We bouwden een verkeerslicht met de Arduino Yun: drie LEDs en een RTC. De lichten schakelen op vast intervallen. De Yun slaat de Unix-tijdstippen van de volgende groene/rode fasen op en voert een PHP-script uit dat de data in de MySQL-database schrijft. Een Android-app (Android Studio) haalt de data via een JSON-PHP-script op, berekent de gewenste snelheid en toont een afteller.

Slim Verkeerslichtsysteem met Real-Time Data

De afstand tot het verkeerslicht wordt gemeten met een HC-SR04 ultrasone sensor op een tweede Arduino (zender). De data wordt via 433 MHz RF-modules naar de Yun (ontvanger) gestuurd en elke meting updatet de database. Zo kan de app realtime de optimale snelheid berekenen.

Slim Verkeerslichtsysteem met Real-Time Data

Instructies

  1. Maak een online MySQL-database aan (bijv. freemysqlhosting.net).
  2. Voeg tabel 'TrafficL_data' toe met kolommen: UnixTime_green_1, UnixTime_red_1, UnixTime_green_2, UnixTime_red_2, Distance, id.
  3. Bouw de zender-hardware (schema: 'Arduino transmitter').
  4. Upload 'Arduino Transmitter Code' naar de zender-Arduino.
  5. Verbinden Arduino Yun met WiFi.
  6. Toegang tot Linux-server van Yun via PuTTY:
    opkg update
    opkg install php5-mod-mysqli php5-cli nano
    nano /mnt/sda1/MySQL_UpdateTrafficLData.php
    chmod 755 /mnt/sda1/MySQL_UpdateTrafficLData.php
    nano /mnt/sda1/MySQL_UpdateDistance.php
    chmod 755 /mnt/sda1/MySQL_UpdateDistance.php
    
    PHP-bestanden vind je in de code-sectie.
  7. Bouw de ontvanger-hardware (Arduino Yun) (schema: 'Arduino Yun receiver').
  8. Upload 'Arduino Receiver & MySQLdb' naar de Yun.
  9. Open Seriële Monitor voor debugging.
  10. Android Studio-project: pas de URL in MainActivity.java aan, compileer en installeer op smartphone.

Alternatief met ESP8266 (goedkoper)

Vervang de Arduino Yun door een ESP8266-gebaseerd bord (bijv. NodeMCU V3). Gebruik 000webhost.com voor gratis hosting en database. Upload CreateTable.php en PostDemo.php via File Manager. Installeer ESP8266-ondersteuning in Arduino IDE (board manager URL: https://arduino.esp8266.com/stable/package_esp8266com_index.json). Upload ESP8266PostDemo.ino (ziet willekeurige testdata elke 10 sec). Pas vervolgens de Yun-functies MySQL_UpdateTrafficLData() en MySQL_UpdateDistance() aan om naar de ESP8266-endpoint te schrijven.

Slim Verkeerslichtsysteem met Real-Time Data

Tip: test elk deel apart voordat je alles combineert. Vraag gerust hulp in de reacties.

Code

  • Arduino Transmitter Code
  • Arduino Receiver & MySQLdb
  • MySQL_UpdateTrafficLData.php
  • MySQL_UpdateDistance.php
  • EchoJSON.php
  • MainActivity.java
  • AndroidManifest.xml
  • strings.xml
  • activity_main.xml

Arduino Transmitter Code

/* IOTOPIA - 2016-2017 - Traffic Light Information System (Transmitter)
 * by Pieter Luyten & Joppe Smeets
 * Send distance via RF 433MHz
 */
#define tx_pin 3
#define trig_pin 5
#define echo_pin 6
#include <VirtualWire.h>
#include "HCSR04.h"
HCSR04 ultrasonic(trig_pin, echo_pin);
int distance;
char CharMsg[21];
void setup() {
  Serial.begin(9600);
  vw_setup(2000);
  vw_set_tx_pin(tx_pin);
}
void loop() {
  distance = ultrasonic.Ranging(CM);
  while (distance < 0) distance = ultrasonic.Ranging(CM);
  sprintf(CharMsg, "%d,", distance);
  vw_send((uint8_t *)CharMsg, strlen(CharMsg));
  vw_wait_tx();
  Serial.print("Distance (cm): ");
  Serial.println(distance);
  delay(250);
}

Arduino Receiver & MySQLdb

/* IOTOPIA - 2016-2017 - Traffic Light Information System (Receiver + Upload to MySQLdb)
 * by Pieter Luyten & Joppe Smeets
 */
#define RedLED 5
#define OrangeLED 6
#define GreenLED 7
#define rx_pin 9
#include <VirtualWire.h>
#include <TimeAlarms.h>
#include <Wire.h>
#include "RTClib.h"
#include <Process.h>
long UnixTime_green_1, UnixTime_red_1, UnixTime_green_2, UnixTime_red_2;
long s_till_orange;
RTC_DS3231 rtc;
char StringReceived[22];
boolean i;
int interval = 5;
int distance;
void setup() {
  rtc.begin();
  Serial.begin(9600);
  Bridge.begin();
  vw_setup(2000);
  vw_set_rx_pin(rx_pin);
  vw_rx_start();
  Alarm.timerRepeat(interval, UpdateTrafficLData);
  Alarm.timerRepeat(1, PrintCurrentTime);
  pinMode(GreenLED, OUTPUT);
  pinMode(OrangeLED, OUTPUT);
  pinMode(RedLED, OUTPUT);
  digitalWrite(GreenLED, LOW);
  digitalWrite(OrangeLED, LOW);
  digitalWrite(RedLED, LOW);
  Serial.println("Setup finished");
}
void loop() {
  Alarm.delay(0);
  RF_Listen();
}
void RF_Listen() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) {
    for (int a = 0; a < buflen; a++) StringReceived[a] = char(buf[a]);
    sscanf(StringReceived, "%d", &distance);
    MySQL_UpdateDistance();
    Serial.print("Distance: ");
    Serial.println(distance);
  }
  memset(StringReceived, 0, sizeof(StringReceived));
}
void UpdateTrafficLData() {
  DateTime now = rtc.now();
  if (i == 1) {
    UnixTime_green_1 = now.unixtime() + interval + 1;
    UnixTime_red_1 = now.unixtime() + 2 * interval + 1;
    UnixTime_green_2 = now.unixtime() + 3 * interval + 1;
    UnixTime_red_2 = now.unixtime() + 4 * interval + 1;
    MySQL_UpdateTrafficLData();
    i = 0;
  } else {
    UnixTime_red_1 = now.unixtime() + interval + 1;
    UnixTime_green_1 = now.unixtime() + 2 * interval + 1;
    UnixTime_red_2 = now.unixtime() + 3 * interval + 1;
    UnixTime_green_2 = now.unixtime() + 4 * interval + 1;
    MySQL_UpdateTrafficLData();
    i = 1;
  }
  Serial.print(" Green_1 at "); Serial.print(UnixTime_green_1);
  Serial.print(" Red_1 at "); Serial.print(UnixTime_red_1);
  Serial.print(" Green_2 at "); Serial.print(UnixTime_green_2);
  Serial.print(" Red_2 at "); Serial.println(UnixTime_red_2);
}
void MySQL_UpdateTrafficLData() {
  long dataArray[4] = {UnixTime_green_1, UnixTime_red_1, UnixTime_green_2, UnixTime_red_2};
  Process p;
  p.begin("/mnt/sda1/MySQL_UpdateTrafficLData.php");
  for (int b = 0; b < 4; b++) p.addParameter(String(dataArray[b]));
  p.run();
  while (p.available() > 0) { char c = p.read(); Serial.print(c); }
  Serial.flush();
}
void MySQL_UpdateDistance() {
  Process p;
  p.begin("/mnt/sda1/MySQL_UpdateDistance.php");
  p.addParameter(String(distance));
  p.run();
  while (p.available() > 0) { char c = p.read(); Serial.print(c); }
  Serial.flush();
}
void PrintCurrentTime() {
  DateTime now = rtc.now();
  SetLEDsTrafficL();
  Serial.print(now.hour()); Serial.print(':'); Serial.print(now.minute()); Serial.print(':'); Serial.print(now.second());
  Serial.print(" "); Serial.println(now.unixtime());
}
void SetLEDsTrafficL() {
  DateTime now = rtc.now();
  s_till_orange = UnixTime_red_1 - now.unixtime();
  if (i == 0) { digitalWrite(GreenLED, LOW); digitalWrite(OrangeLED, LOW); digitalWrite(RedLED, HIGH); }
  if (i == 1 && s_till_orange <= 3) { digitalWrite(GreenLED, LOW); digitalWrite(OrangeLED, HIGH); digitalWrite(RedLED, LOW); }
  if (i == 1 && s_till_orange > 3) { digitalWrite(GreenLED, HIGH); digitalWrite(OrangeLED, LOW); digitalWrite(RedLED, LOW); }
}

MySQL_UpdateTrafficLData.php

#!/usr/bin/php-cli
<?php
$UnixTime_green_1 = $argv[1];
$UnixTime_red_1 = $argv[2];
$UnixTime_green_2 = $argv[3];
$UnixTime_red_2 = $argv[4];
$DBServer = 'yourServerName';
$DBUser = 'yourUserName';
$DBPass = 'yourPassword';
$DBName = 'yourDBName';
$conn = new mysqli($DBServer, $DBUser, $DBPass, $DBName);
if ($conn->connect_error) trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR);
$sql = "UPDATE TrafficL_data SET UnixTime_green_1='$UnixTime_green_1', UnixTime_red_1='$UnixTime_red_1', UnixTime_green_2='$UnixTime_green_2', UnixTime_red_2='$UnixTime_red_2' WHERE id=1";
if ($conn->query($sql) === false) trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
else echo "Data inserted!\n";
?>

MySQL_UpdateDistance.php

#!/usr/bin/php-cli
<?php
$Distance = $argv[1];
$DBServer = 'yourServerName';
$DBUser = 'yourUserName';
$DBPass = 'yourPassword';
$DBName = 'yourDBName';
$conn = new mysqli($DBServer, $DBUser, $DBPass, $DBName);
if ($conn->connect_error) trigger_error('Database connection failed: ' . $conn->connect_error, E_USER_ERROR);
$sql = "UPDATE TrafficL_data SET Distance='$Distance' WHERE id=1";
if ($conn->query($sql) === false) trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
else echo "Distance inserted!\n";
?>

EchoJSON.php

<?php
define('HOST','yourServerName');
define('USER','yourUserName');
define('PASS','yourPassword');
define('DB','yourDBName');
$con = mysqli_connect(HOST,USER,PASS,DB);
$sql = "select * from TrafficL_data";
$res = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($res,MYSQLI_BOTH)){
  printf('[ { "TrafficLArray":[ { "UnixTime_green_1":"%s", "UnixTime_red_1":"%s", "UnixTime_green_2":"%s", "UnixTime_red_2":"%s", "Distance":"%s" } ] } ]',
    $row['UnixTime_green_1'], $row['UnixTime_red_1'], $row['UnixTime_green_2'], $row['UnixTime_red_2'], $row['Distance']);
}
mysqli_close($con);
?>

MainActivity.java (kern)

package com.example.xxx.xxx; // aanpassen
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {
  TextView results, recSpeed;
  String JsonURL = "YourURLhere";
  RequestQueue requestQueue;
  private final static double maxSpeed = 18; // cm/s
  private double speed, distance;
  public final static int NUMBER_OF_ENTRIES = 2;
  long[] unixTimesGreen = new long[NUMBER_OF_ENTRIES];
  long[] unixTimesRed = new long[NUMBER_OF_ENTRIES];
  private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    results = findViewById(R.id.jsonData);
    recSpeed = findViewById(R.id.recommendedSpeed);
    updateTable();
    scheduler.scheduleAtFixedRate(this::updateTable, 0, 500, TimeUnit.MILLISECONDS);
  }

  private void updateTable() {
    requestQueue = Volley.newRequestQueue(this);
    JsonArrayRequest arrayreq = new JsonArrayRequest(JsonURL,
      response -> {
        try {
          JSONObject TrafficLObj = response.getJSONObject(0);
          JSONArray trafficArry = TrafficLObj.getJSONArray("TrafficLArray");
          for (int i = 0; i < trafficArry.length(); i++) {
            JSONObject jsonObject = trafficArry.getJSONObject(i);
            distance = Double.parseLong(jsonObject.getString("Distance"));
            unixTimesGreen[0] = Long.parseLong(jsonObject.getString("UnixTime_green_1"));
            unixTimesRed[0] = Long.parseLong(jsonObject.getString("UnixTime_red_1"));
            unixTimesGreen[1] = Long.parseLong(jsonObject.getString("UnixTime_green_2"));
            unixTimesRed[1] = Long.parseLong(jsonObject.getString("UnixTime_red_2"));
          }
          updateTextView();
        } catch (JSONException e) { e.printStackTrace(); }
      },
      error -> Log.e("Volley", "Error")
    );
    requestQueue.add(arrayreq);
  }

  private void updateTextView() {
    speedCalc();
    recSpeed.setText(String.format("%.0f", speed));
  }

  private void speedCalc() {
    double time = System.currentTimeMillis() / 1000.0;
    int interval = 0;
    for (int i = 0; i < NUMBER_OF_ENTRIES; i++) {
      double diff = unixTimesRed[interval] - time;
      speed = distance / (diff / 1000.0);
      interval++;
    }
    interval--;
    if (distance / (unixTimesGreen[interval] - time) > maxSpeed) speed = maxSpeed;
    else speed = distance / (unixTimesGreen[interval] - time);
    speed *= 5; // omrekenfactor
  }
}

Schema's

Zender (Arduino + HC-SR04 + RF 433MHz tx):
tx_pin → pin 3
trig_pin → pin 5
echo_pin → pin 6

Slim Verkeerslichtsysteem met Real-Time Data

Ontvanger (Arduino Yun + LEDs + RTC + RF 433MHz rx):
rx_pin → pin 3
RedLED → pin 5, OrangeLED → pin 6, GreenLED → pin 7
DS3231 SCL → SCL (pin 3 Yun), SDA → SDA (pin 2 Yun)

Slim Verkeerslichtsysteem met Real-Time Data

Productieproces

  1. Gaslampen: Evolutie, Ontwerp en Moderne Productie
  2. Laser Pointer: Ontwerp, Productie en Veiligheidsoverzicht
  3. De Kaleidoscoop: Van Brewsters Wetenschap tot Modern Ontwerp
  4. Verkeerslichten: Techniek, Geschiedenis en Toekomstige Innovaties
  5. Light-Emitting Diodes: Van Ontstaan tot 100-Jarige Levensduur
  6. Slimme Verkeerslicht: Adaptieve Straatverlichting Aangedreven door IoT
  7. AI-gestuurde verhoogde-bundel controle verbetert nachtzicht terwijl blindering voorkomt
  8. LED Strip Accessoires Meesteren: Verbinden, Besturen en Uw Verlichting Aanpassen
  9. Robotlas Systeem E-book: Cruciale Investeringsinzichten voor Fabrikanten
  10. Hoogprecisie Continuous-Wave ToF systemen ontwerpen: Een uitgebreid overzicht
  11. Binnenkijken in een Sengled Slimme LED-lamp: Technische Ontbinding en Zigbee Connectiviteit Review