Sunday, November 17, 2024

Rancangan

 Berikut ini komponen yang dibutuhkan

  1. TTGO LORA32 sebanyak 2 buah
  2. Sensor Kecepatan Angin sebanyak 1 buah
  3. Sensor Arah Angin sebanyak 1 buah
  4. Solar Panel sebanyak 1 buah
  5. Battery shield V3 18650 sebanyak 1 buah
  6. Battery 18650 3.7V sebanyak 1 buah
Gambar komponen:

Gambar 1. TTGO LORA32 V2.1 433MHz

Gambar 2. Sensor Kecepatan Angin

Gambar 3. Sensor Arah Angin

Gambar 4. Solar Panel

Gambar 5. Battery Shield V3 18650

Gambar 6. Battery 18650 3.7V


Gambar peta kaki TTGO LORA32:
Gambar 7. Peta kaki TTGO LORA32 V2.1

Penyambungan rangkaian:

Gambar 8. Penyambungan rangkaian: kaki 12 untuk kecepatan angin, kaki 25 untuk arah angin


Kode program untuk pembacaan arah angin:
  1. #include <HardwareSerial.h>
  2. HardwareSerial sensor(1);
  3. unsigned long skr = 0;
  4. String data;
  5. void setup() {
  6.   Serial.begin(9600);
  7.   sensor.begin(9600, SERIAL_8N1, 25, 4);
  8. }
  9. void loop() {
  10.   if (sensor.available()) {
  11.     data = sensor.readString();
  12.   }
  13.   if (millis() - skr > 5000) {
  14.     skr = millis();
  15.     Serial.println(data.substring(1, 2));
  16.   }
  17. }

Kode program untuk pembacaan kecepatan dan arah angin:
  1. #include <HardwareSerial.h>
  2. HardwareSerial sensor(1);
  3. volatile byte rpmcount;
  4. volatile unsigned long last_micros;
  5. unsigned long timeold;
  6. unsigned long durasi = 10.0;
  7. String data;
  8. int pin_kec = 12;
  9. float rps;
  10. float kpj;
  11. float mps;
  12. volatile boolean flag = false;
  13. void ICACHE_RAM_ATTR rpm() {
  14.   flag = true;
  15. }
  16. void setup() {
  17.   Serial.begin(9600);
  18.   sensor.begin(9600, SERIAL_8N1, 25, 4);
  19.   pinMode(pin_kec, INPUT_PULLUP);
  20.   digitalWrite(pin_kec, LOW);
  21.   Serial.begin(9600);
  22.   detachInterrupt(digitalPinToInterrupt(pin_kec));
  23.   attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
  24.   rpmcount = 0;
  25.   timeold = 0;
  26. }
  27. void loop() {
  28.   if (sensor.available()) {
  29.     data = sensor.readString();
  30.   }
  31.   if (flag == true) {
  32.     if (long(micros() - last_micros) >= 5000) {
  33.       rpmcount++;
  34.       last_micros = micros();
  35.     }
  36.     flag = false;
  37.   }
  38.   if ((millis() - timeold) >= durasi * 1000) {
  39.     detachInterrupt(digitalPinToInterrupt(pin_kec));
  40.     rps = float(rpmcount) / float(durasi);
  41.     mps = ((-0.0181 * (rps * rps)) + (1.3859 * rps) + 1.4055);
  42.     if (mps <= 1.5) mps = 0.0;
  43.     kpj = mps * 3.6;  
  44.     Serial.print(data.substring(1, 2));
  45.     Serial.print(",");
  46.     Serial.println(kpj);
  47.     timeold = millis();
  48.     rpmcount = 0;
  49.     attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
  50.   }
  51. }


Kode program untuk menampilkan data kecepatan dan arah angin di OLED:
  1. #include <SPI.h>
  2. #include <LoRa.h>
  3. #include <Wire.h>
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_SSD1306.h>
  6. #include <HardwareSerial.h>
  7. #define SCK 5
  8. #define MISO 19
  9. #define MOSI 27
  10. #define SS 18
  11. #define RST 23
  12. #define DIO0 26
  13. #define BAND 433E6
  14. #define OLED_SDA 21
  15. #define OLED_SCL 22
  16. Adafruit_SSD1306 display(128, 64, &Wire, -1);
  17. HardwareSerial sensor(1);
  18. volatile byte rpmcount;
  19. volatile unsigned long last_micros;
  20. unsigned long timeold;
  21. unsigned long durasi = 2.0;
  22. String data;
  23. int arah = 0;
  24. int pin_kec = 12;
  25. float rps;
  26. float kpj;
  27. float mps;
  28. volatile boolean flag = false;
  29. void ICACHE_RAM_ATTR rpm() {
  30.   flag = true;
  31. }
  32. void setup() {
  33.   Serial.begin(9600);
  34.   Wire.begin(OLED_SDA, OLED_SCL);
  35.   if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) {  // Address 0x3C for 128x32
  36.     Serial.println(F("SSD1306 allocation failed"));
  37.     for (;;)
  38.       ;
  39.   }
  40.   sensor.begin(9600, SERIAL_8N1, 25, 4);
  41.   pinMode(pin_kec, INPUT_PULLUP);
  42.   digitalWrite(pin_kec, LOW);
  43.   Serial.begin(9600);
  44.   detachInterrupt(digitalPinToInterrupt(pin_kec));
  45.   attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
  46.   rpmcount = 0;
  47.   timeold = 0;
  48.   display.clearDisplay();
  49.   display.setTextColor(WHITE);
  50.   display.setTextSize(1);
  51.   display.setCursor(0, 0);
  52.   display.print("LORA SENDER ");
  53.   display.display();
  54.   Serial.println("LoRa Sender Test");
  55.   SPI.begin(SCK, MISO, MOSI, SS);
  56.   LoRa.setPins(SS, RST, DIO0);
  57.   if (!LoRa.begin(BAND)) {
  58.     Serial.println("Starting LoRa failed!");
  59.     while (1)
  60.       ;
  61.   }
  62.   Serial.println("LoRa Initializing OK!");
  63.   display.setCursor(0, 10);
  64.   display.print("LoRa Initializing OK!");
  65.   display.display();
  66.   delay(2000);
  67. }
  68. void loop() {
  69.   if (sensor.available()) {
  70.     data = sensor.readString();
  71.     arah = data.substring(1, 2).toInt();
  72.   }
  73.   if (flag == true) {
  74.     if (long(micros() - last_micros) >= 5000) {
  75.       rpmcount++;
  76.       last_micros = micros();
  77.     }
  78.     flag = false;
  79.   }
  80.   if ((millis() - timeold) >= durasi * 1000) {
  81.     detachInterrupt(digitalPinToInterrupt(pin_kec));
  82.     rps = float(rpmcount) / float(durasi);
  83.     mps = ((-0.0181 * (rps * rps)) + (1.3859 * rps) + 1.4055);
  84.     if (mps <= 1.5) mps = 0.0;
  85.     kpj = mps * 3.6;
  86.     LoRa.beginPacket();
  87.     LoRa.print(arah);
  88.     LoRa.print(",");
  89.     LoRa.print(kpj);
  90.     LoRa.endPacket();
  91.     display.clearDisplay();
  92.     display.setTextSize(1);
  93.     display.setCursor(0, 0);
  94.     display.print("Arah Angin: ");
  95.     display.setTextSize(2);
  96.     display.setCursor(0, 10);
  97.     display.print(arah);
  98.     display.setTextSize(1);
  99.     display.setCursor(0, 35);
  100.     display.print("Kecepatan: ");
  101.     display.setTextSize(2);
  102.     display.setCursor(0, 45);
  103.     display.print(kpj);
  104.     display.print(" kpj");
  105.     display.display();
  106.     Serial.print(arah);
  107.     Serial.print(",");
  108.     Serial.println(kpj);
  109.     timeold = millis();
  110.     rpmcount = 0;
  111.     attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
  112.   }
  113. }



Kode program untuk meneruskan data dan menampilkannya di Thingspeak

#include <WiFi.h>
#include "ThingSpeak.h" #include <SPI.h>
#include <LoRa.h> #include <Wire.h>
#include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
#define SCK 5 #define MISO 19
#define MOSI 27 #define SS 18
#define RST 23 #define DIO0 26
#define BAND 433E6 #define OLED_SDA 21
#define OLED_SCL 22 Adafruit_SSD1306 display(128, 64, &Wire, -1);
const char* WIFI_NAME = "MEKATRONIKA"; const char* WIFI_PASSWORD = "robotika";
const int myChannelID = 2752567; const char* myApiKey = "QDDDHSF22EWOUGZ1";
const char* server = "api.thingspeak.com"; WiFiClient client;
String LoRaData; void setup() {
Serial.begin(115200); WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) { delay(1000);
Serial.println("Wifi not connected"); }
Serial.println("Wifi connected !"); Serial.println("Local IP: " + String(WiFi.localIP()));
WiFi.mode(WIFI_STA); ThingSpeak.begin(client);
Wire.begin(OLED_SDA, OLED_SCL); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) {
Serial.println(F("SSD1306 allocation failed")); for (;;);
} display.clearDisplay();
display.setTextColor(WHITE); display.setTextSize(1);
display.setCursor(0, 0); display.print("LORA RECEIVER ");
display.display(); Serial.println("LoRa Receiver Test");
SPI.begin(SCK, MISO, MOSI, SS); LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(BAND)) { Serial.println("Starting LoRa failed!");
while (1); }
Serial.println("LoRa Initializing OK!"); display.setCursor(0, 10);
display.println("LoRa Initializing OK!"); display.display();
} void loop() {
int packetSize = LoRa.parsePacket(); if (packetSize) {
Serial.print("Received packet "); while (LoRa.available()) {
LoRaData = LoRa.readString(); Serial.print(LoRaData);
} String d0 = getValue(LoRaData, ',', 0); //arah
String d1 = getValue(LoRaData, ',', 1); //kec int rssi = LoRa.packetRssi();
display.clearDisplay(); display.setTextSize(1);
display.setCursor(0, 0); display.print("Arah Angin: ");
display.setTextSize(2); display.setCursor(0, 10);
display.print(d0); display.setTextSize(1);
display.setCursor(0, 35); display.print("Kecepatan: ");
display.setTextSize(2); display.setCursor(0, 45);
display.print(d1); display.print(" kpj");
display.display(); ThingSpeak.setField(1, d0);
ThingSpeak.setField(2, d1); int status = ThingSpeak.writeFields(myChannelID, myApiKey);
} }
String getValue(String data, char separator, int index) { int found = 0;
int strIndex[] = { 0, -1 }; int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) {
found++; strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i; }
} return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}


Hasil Program:









Rancangan

 Berikut ini komponen yang dibutuhkan TTGO LORA32 sebanyak 2 buah Sensor Kecepatan Angin sebanyak 1 buah Sensor Arah Angin sebanyak 1 buah S...