پارکینگ هوشمند

فهرست

مقدمه

اندازه گیری فاصله و عمق سنجی از ابزارهای کار آمدی است که کاربردهای متنوعی می تواند داشته باشد. تشخیص حضور خودرو در محل پارک در پارکینگ های عمومی یکی از کاربردهای این ابزار است. از کاربردهای دیگر آن می توان به تشخیص میزان زباله موجود در باکس ها وسطل های زباله جهت یافتن زمان بهینه برای تخلیه آنها و جلوگیری از سریز شدن زباله، اشاره کرد.

عمق سنجی در تشخیص سطح آب رودها و رودخانه ها جهت سامانه هشدار سیل و یا جهت تشخیص میزان مواد موجود در مخازن و سیلوها  و کاربردهای بسیار خلاقانه دیگر می تواند مورد استفاده قرار گیرد.

در این مقاله سعی می کنیم یک کیت عمق سنجی را با استفاده از محصولات ماژولار ProMake بسازیم و در پنل وب وضعیت دریافت شده از حسگر  را نمایش دهیم.

اقلام مورد نیاز برای ساخت حسگر حضور خودرو

برای این که یک حسگر حضور  خودرو ساده داشته باشید نیاز به اقلام زیر داریم:

  1. برد آردوینو اونو(Arduino UNO) + کابل USB مناسب برای پروگرم کردن آن
  2. شیلد ماژولار آردوینو پرومیک(ProMake Arduino Shield)
  3. ماژول ProMake WiFi ESP12(که از ESP8266 برای ارتباط با شبکه وای فای استفاده می کند)
  4. حسگر فراصوت(Ulterasonic) برای سنجش فاصله
  5. یک جعبه با سایز مناسب 
در این پروژه به علت اینکه در فضای پارکینگ قرار هست از این کیت استفاده بشه از ارتباط WiFi استفاده کردیم. اما شما می‌توانید با هریک از ماژول‌های ارتباطی ProMake که برای پروژه شما مناسب هست این کار را انجام بدین.

برای آشنایی بیشتر با محصولات به کار رفته در این کیت برروی آنها کلیک کنید

wifi-001( janbi )

WiFi ESP12

معروف‌ترین ماژول برای ارتباط با شبکه‌های WiFi در اختیار شماست.

سرهم کردن کیت

ابتدا “ProMake Arduino Shield” را بر روی برد آردوینو اونو(Arduino UNO) قرار دهید، سپس خیلی ساده مطابق شکل :

  1. ماژول ProMake WiFi ESP12 را در محل شماره 1 قرار دهید.
  2. کابل Grove حسگر فراصوت را به کانکتور J4 روی شیلد پرومیک متصل کنید.
توجه: در هنگام وارد کردن ماژول‌های پرومیک به جهت آنها که از بریدگی گوشه آنها قابل تشخیص است دقت کنید.
توجه: حتماً هر ماژول را در محل تعیین شده وارد نمایید تا اتصالات مورد نیاز برای ارتباط با ماژول فراهم باشد.

حال باید کیت شما مطابق شکل روبرو باشد.

برنامه نویسی و بارگزاری(Upload) روی برد

برای برنامه نویسی از محیط معروف و دوست داشتنی Arduino IDE استفاده می‌کنیم. پس اگر آن را برروی رایانه شخصیتون نصب ندارید، سریع نصبش کنید تا بریم سراغ مرحله بعد…

نصب کتابخانه WiFiEsp 

برای اینکه بتونیم با ماژول ESP8266 ارتباط برقرار کنیم باید کتابخانه WiFiEsp را در Arduino IDE نصب نمایید.

برای اینکار کافی است از منو Sketch وارد زیر منو Include Library شوید و آیتم Manage Libraries را انتخاب نمایید و در پنجره ظاهر شده مطابق تصویر رو به رو عبارت WiFiEsp را جستجو نمایید. بعد از ظاهر شدن نتایج برروی دکمه Install کلیک نمایید تا کتابخانه نصب شود.

آیتم Manage Libraries از منو Tools نیز قابل دسترس است و البته با استفاده از کلید ترکیبی Ctrl+Shift+I نیز  ظاهر می شود.

نصب کتابخانه FastLED  

برای کنترل RGB LED های روی شیلد، کتابخانه Fast LED را در Arduino IDE نصب نمایید.

برای اینکار کافی است از منو Sketch وارد زیر منو Include Library شوید و آیتم Manage Libraries را انتخاب نمایید و در پنجره ظاهر شده مطابق تصویر رو به رو عبارت FastLED  را جستجو نمایید. بعد از ظاهر شدن نتایج برروی دکمه Install کلیک نمایید تا کتابخانه نصب شود.

کتابخانه FastLED

ایجاد حساب کاربری Ubidots

برای اینکه بتوانید وضعیت حسگر را برروی داشبرد مشاهده کنید می بایست برروی یک سرویس دهند اینترنتی پلتفورم IoT یک حساب کاربری داشته باشید. در این پروژه ما سرویس ubidots را به عنوان یک نمونه که به صورت رایگان در اختیار همه قرار دارد انتخاب کردیم.

پس به سایت https://ubidots.com مراجعه نمایید و برای خود یک حساب کاربری رایگان ایجاد نمایید.

سایت ubidots.com

آشنایی با کد

حال که کتابخانه‌های پیش نیاز را نصب کردید و حساب کاربری ubidots را ساخته اید، آماده هستید تا وارد نوشتن برنامه اصلی شوید.

عجله نکنید!! ابتدا نیاز است تغییراتی در کد زیر بدهید و بعد از آن استفاده کنید، لذا لطفا گام به گام با من همراه شوید تا هم کد را برایتان شرح دهم و هم تغییرات را باهم اعمال کنیم

  • در خطوط 1 تا 7 شیئ  RGB LED را ایجاد کردیم و پین مربوطه را از  روی مارکاژ برد استخراج و  تعریف  نمودیم.
  • در خطوط 7 تا 16 متغییرهای مورد نیاز برای سنجش فاصله را تعریف کردیم. دقت کنید که متغییر maxDistance را با حداکثر فاصله کف پارکینگ از محل نصب سنسور مقداردهی کنید.
  • در خطوط 16 تا 31 پین های  مربوط به ارتباط UART و RESET ماژول WiFi را  با دقت از روی مارکاژهای شیلد و ماژول  استخراج و  تعریف کردیم. سپس اشیاء مورد نیاز را ایجاد نمودیم.
    • برای ارتباط با مودم وای فای شناسه شبکه(SSID) و کلمه عبور را در خطوط 27 و 28 اصلاح نمایید.
  • در خطوط 34 تا 39  آدرس و پورت سرور HTTP سایت Ubidots را تنظیم نمودیم. همچنین فاصله زمانی بین ارسال‌های پیاپی را نیز تنظیم نمودیم.
  • در تابع setup :
    • ارتباط سریال Debug را راه اندازی کردیم.
    • جهت پین‌های حسگر فراصوت را تنظیم نمودیم.
    • سپس چراغ‌های RGB LED را راه اندازی می‌کنیم.
    • ماژول ESP8266 را ریست و با پارامترهای صحیح راه اندازی می کنیم.
    • سپس تلاش می کنیم تا به شبکه WiFi وصل شویم.
  • در تابع loop:
    • ابتدا  پایه تحریک(trig) حسگر فراصوت را برای 2 میلی ثانیه پایین نگه می‌داریم تا سکوت کامل حکمفرما شود. سپس برای 10 میلی ثانیه بالا می‌آوریم تا امواج ارسال شوند و مجدد پایین می‌آوریم تا ارسال قطع شود.
    • سپس بلافاصله بازه زمانی تا پایین آمدن سیگنال پایه اکو(echo) را اندازه می‌گیریم تا زمانی را که طول می‌کشد تا انعکاس امواج ارسالی قطع شوند را اندازگیری کنیم.
    • حال با داشتن سرعت انتشار صوت و احتساب زمان رفت و برگشت موج می‌توانیم فاصله نزدیک‌ترین منعکس کننده را اندازه گیری کنیم.
    • در صورتی که فاصله اندازگیری شده از maxDistance کمتر باشد نشان دهنده حضور خودرو در محل پارک می‌باشد.
      • برای اینکه عوامل خطا باعث تشخیص نادرست نشوند مقدار 20 سانت نیز  به عنوان حاشیه خطا در نظر گرفتیم.
    • در صورت تشخیص حضور خودرو دو چراغ RGB LED را قرمز می‌کنیم و در غیر این صورت آن دو را سبز می‌کنیم.
    • سپس  در صورتی که بیش از  10 ثانیه از  ارسال داده قبلی گذشته باشد یا تغییری در پر یا خالی شدن محل پارک رخ داده باشد، داده‌های جدید را به صورت یک رشته با فرمت JSON برای سرور ارسال می‌کنیم.
      • داده‌های ارسالی برای سرور حاوی حضور یا عدم حضور خودرو(Occ) و ارتفاع تقریبی خودرو(Car) می‌باشد.
  • در تابع http_post اقدام به ارسال رشته دریافت شده در آرگومان ورودی تابع با استفاده از HTTP می‌کنیم.
    • برای اینکه داده‌های حسگرها برای حساب کاربری شما ارسال شود می‌بایست Default token حساب خود را در بخشی از کد که عبارت REPLACE_YOUR_TOKEN نوشته شده جایگزین کنید. در ادامه در باره این که چگونه این توکن را از سایت دریافت کنید توضیح خواهم داد.
				
					//RGB LEDs ==========================================
#include <FastLED.h>
#define LED_PIN     16
#define NUM_LEDS    2
CRGB leds[NUM_LEDS];

//Sensor ==========================================
#define echoPin 15 // Echo of HC-SR04
#define trigPin 6 // Trig of HC-SR04

long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
int maxDistance = 200;
bool lastState;

// WiFi UART Connection =================================
#include <SoftwareSerial.h>
#define ARD_RX_ESP_TX   4 // Arduino RX = ESP TX
#define ARD_TX_ESP_RX   7 // Arduino TX = ESP RX
SoftwareSerial EspSerial(ARD_RX_ESP_TX, ARD_TX_ESP_RX); 

#define ESP_AT_BAUD     9600  
#define ESP_RST_PIN     8

#include "WiFiEsp.h"

char ssid[] = "YOUR_SSID";            // your network SSID (name)
char pass[] = "YOUR_PASSWORD";        // your network password

// Initialize the Ethernet client object
WiFiEspClient client;

// IOT Platform ===================================
#define SERVER_NAME   "169.55.61.243" //"industrial.api.ubidots.com"
#define SERVER_PORT   (80)

unsigned long lastConnectionTime = 0;         // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 10000L; // delay between updates, in milliseconds
//const unsigned long postingInterval = 600000L; // delay between updates, in milliseconds


void setup(void)
{
  Serial.begin(9600);
  while (!Serial);
  
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT

  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  
  pinMode(ESP_RST_PIN, OUTPUT);
  //ESP RESET
  digitalWrite(ESP_RST_PIN, LOW);
  delay(50);
  digitalWrite(ESP_RST_PIN, HIGH);
  delay(2000); // to boot

  // initialize serial for ESP module
  EspSerial.begin(ESP_AT_BAUD);
  // initialize ESP module
  WiFi.init(&EspSerial);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi module not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  int status = WL_IDLE_STATUS;     // the Wifi radio's status
  while ( status != WL_CONNECTED) {
    Serial.print(F("Connecting to WPA SSID: "));
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
  Serial.println("You're connected to the network");
}

void loop(void)
{
  // Clears the trigPin condition
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  
  // Displays the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  bool occupied = false;
  if(distance < (maxDistance - 20)){
    occupied = true;
    leds[0] = CRGB(255, 0, 0);
    leds[1] = CRGB(255, 0, 0);
    FastLED.show();
  }else{
    leds[0] = CRGB(0, 255, 0);
    leds[1] = CRGB(0, 255, 0);
    FastLED.show();
  }

  // if postingInterval seconds have passed since your last connection,
  // then connect again and send data
  if (millis() - lastConnectionTime > postingInterval || lastState != occupied) {
    Serial.println("Sending Data ...");
    lastState = occupied;
    http_post(String(F("{\"Car\":"))+ String(maxDistance - distance)+
              String(F(",\"Occ\":")) + String(occupied)+
              String("}"));
  }
  
  delay(1000);
}

void http_post( String postdata) {
  // close any connection before send a new request
  // this will free the socket on the WiFi module
  client.stop();
  
  if (client.connect(SERVER_NAME, SERVER_PORT)) 
  {
    Serial.println("Sending Req ...");
    // Sending the HTTP request
    client.println(("POST /api/v1.6/devices/parking/ HTTP/1.1"));
    client.println(F("Host: industrial.api.ubidots.com"));
    client.println(F("User-Agent: ESP8266/1.0"));
    client.println(F("X-Auth-Token: REPLACE_YOUR_TOKEN"));
    client.println(F("Content-Type: application/json"));
    client.print(F("Content-Length: "));
    client.println(String(postdata.length()));
    client.println(F("Connection: close"));
    client.println();
    client.println(postdata);
    delay(100);
    
    Serial.println("Waiting Res ...");
    // if there are incoming bytes available
    // from the server, read them and print them
    while (client.connected());
    while (client.available()) {
      char c = client.read();
      Serial.write(c);      // note the time that the connection was made
   }
    lastConnectionTime = millis();  
    Serial.println();
    Serial.println("Disconnecting from server...");
  } 
  else 
  {
   Serial.println(F("Connect failed"));
  }
}
				
			

دریافت Default token از Ubidots

برای ارسال هر درخواست به ubidots نیاز مند TOKEN است. ساده ترین راه برای دریافت توکن ، انتخاب گزینه API Credentials” از منو کاربر در گوشه راست بالای سایت است. برای این کار:

  1. وارد حساب کاربری خود در سایت Ubidots شوید.
  2. وارد منو کاربر در گوشه سمت راست بالا شوید و برروی گزینه API Credentials” کلیک کنید.
  3. حال در فرمی کنه نمایش داده می شود از بخش Tokens مقدار Default token را با استفاده از دکمه مقابل آن کپی کنید. مراقب باشید که توکن را با API Key اشتباه نگیرید!!

بارگذاری کد برروی برد

حال در محیط Arduino IDE :

  • یک Sketch جدید ایجاد نماید و برنامه فوق را  داخل آن کپی نماید.
  •   عبارت YOUR_SSID را با  شناسه شبکه(SSID) و عبارت YOUR_PASSWORD را با کلمه عبور  مودم وای فای جایگزین نمایید.
  • عبارت REPLACE_YOUR_TOKEN را با Default token دریافتی از سایت جایگزین نمایید.
  • حال Sketch را با نامی دلخواه مثل parking ذخیره نمایید.
  • بررسی کنید که کلید S1 روی شیلد در وضعیت PROG قرار داشته باشد.
  • حال می‌توانید برنامه را برروی برد آردوینو اونو بارگذاری(Upload) نمایید.

تست اولیه

برای اینکه قبل از انجام تست میدانی از عملکرد درست مدار اطمینان حاصل کنید:

  • یک فضای مناسب را جهت تست انتخاب کنید. مثلا فاصله تا سقف یا دیوار  را با قرار دادن حسگر فراصوت برروی میزکار و تنظیم جهت آن اندازگیری نماید.
  •  حال با آوردن دست خود جلوی سنسور می‌توانید حضور یک خودرو را شبیه سازی کنید.(دقت کنید که دست شما باید حداقل 10 سانت با حسگر فاصله داشته باشد تا اندازه گیری به صورت صحیح انجام شود)

برای تغذیه برد از روش های زیر می‌توانید استفاده کنید:

  • با استفاده از پورت USB کامپیوتر  یا یک شارژر موبایل یا پاور بانک و یک کابل USB مناسب و اتصال آنها به کانکتور USB ماژول آردوینو اونو؛ تغذیه شیلد، ماژول‌ها و آردوینو را تامین کنید.
  • با استفاده از پورت USB کامپیوتر  یا یک شارژر موبایل یا پاور بانک و یک کابل USB Type-C و اتصال آنها به کانکتور USB Type-C روی شیلد؛ تغذیه شیلد، ماژول‌ها و آردوینو را تامین کنید.
  • با استفاده از یک منبع تغذیه و اتصال آن به کاتکنور بشکه ای پاور برد آردوینو اونو؛ تغذیه شیلد، ماژول‌ها و آردوینو را تامین کنید.

با برقرار شدن تغذیه علایم زیر مشاهده می‌شود:

  • ماژول WiFi راه اندازی شده و در صورت موفقیت در ارتباط با مودم وای فای دو چراغ RGB LED سبز رنگ می‌شوند.
  • حال اگر مانعی سر راه حسگر فراصوت قرار گیرد دو چراغ قرمز رنگ می‌شوند و با کنار رفتن مانع چراغ ها مجدد سبز می‌شوند.
  • همانطور که پیش‌تر اشاره شد با تغییر وضعیت حسگر یا با توجه به بازه زمانی گذشته از ارسال قبلی، داده‌های جدید برای سایت Ubidots ارسال می‌شوند.
  • با اول این ارسال، در سایت Ubidots یک دستگاه به نام parking برای شما ثبت می‌شود که دارای دو متغییر  به نامهای Car و Occ است که به ترتیب حاوی ارتفاع تخمینی خودرو و خالی یا پر بودن فضای پارک هستند.

مشاهده اطلاعات برروی داشبرد

حالا برای مشاهده داده‌های ارسالی کافی هست مراحل زیر را طی کنید:

  • وارد حساب کاربری خود در سایت Ubidots بشوید.
  • از منوی Data آیتم Dashboards را انتخاب کنید.
  • یک داشبرد جدید با نام دلخواه ایجاد کنید.
  • به این داشبرد یک ویجت از نوع Tank و یکی از نوع Indicator مطابق شکل رو برو اضافه نمایید.
  • در بخش Settings ویجت Tank، فیلد Select Devices دستگاه parking را انتخاب نمایید. سپس متغییر Car را انتخاب کنید و با زدن دکمه تایید شکل مخزن مانندی به داشبرد افزوده می‌شود.
  • در بخش Settings ویجت Indicator ، فیلد Select Devices دستگاه parking را انتخاب نمایید. سپس متغییر Occ را انتخاب کنید و با زدن دکمه تایید شکل LED مانندی به داشبرد افزوده می شود‌

برای اینکه نمایش مناسب تری از وضعیت پارکینگ داشته باشید مراحل زیر را طی کنید:

  • در بخش APPEARANCE ویجت Indicator ، برروی قسمت Add color logic کلیک نمایید.
  • در پنجره پدیدار شده می توانید مطابق شکل روبه رو متن و رنگ معادل هر مقدار را مشخص نمایید.

در صورت وجود خودرو در پارکینگ داشبرد شما به صورت زیر خواهد بود

    در صورت عدم وجود خودرو در پارکینگ داشبرد شما به صورت زیر خواهد بود

      بهبودهای نرم افزاری

      همان طور که شاید تاکنون متوجه شده باشید این برنامه تا تبدیل شدن به یک حسگر پارکینگ هوشمند ایده آل فاصله زیادی  دارد. در ادامه به برخی بهبودهای نرم افزاری که می‌شود در این برنامه لحاظ نمود اشاره خواهیم داشت:

      • نمایش وضعیت ارتباط با شبکه WiFi: همان طور که شاید تا کنون متوجه شده باشید وضعیت ارتباط با Access Point به کاربر نمایش داده نمی‌شود و در صورتی که یکی از حسگرهای پارکینگ دچار مشکل ارتباطی شود علامتی به کاربر داده نمی‌شود. برای اینکه با یک نگاه بتوان از برقرار بودن ارتباط WiFi دستگاه مطمئن شد می‌بایست از یکی از RGB LED ها به این منظور استفاده نمود.
      • بهبود ارتباط WiFi: شاید با کمی دقت متوجه شده باشید که اگر ارتباط وای فای به دلیلی مثل خاموش شدن مودم یا تضعیف سیگنال دچار قطعی شود، دیگر اقدامی برای ارتباط مجدد صورت نمی‌گیرد و تمام ارسال‌ها با شکست رو به رو می‌شوند. برای حل این مشکل می‌بایست همواره وضعیت ارتباط با Access Point را بررسی نمود و در صورت بروز قطعی مجدد ارتباط را برقرار نمود.

      بهبودهای سخت افزاری

      چند مورد از بهبودهای سخت افزاری حسگر پارکینگ هوشمند را باهم مرور می‌کنیم:

      1. افزایش حسگرها: این نمونه اولیه شاید برای یک حسگر پارکینگ گران قیمت باشد با استفاده از ماژول ProMake Universal Interface می‌توانید تا سه حسگر فراصوت دیگر را به این کیت اضافه کنید و همزمان 4 فضای پارک را پایش کنید و در هزینه‌ها صرفه جویی کنید.