Berikut ini komponen yang dibutuhkan
- TTGO LORA32 sebanyak 2 buah
- Sensor Kecepatan Angin sebanyak 1 buah
- Sensor Arah Angin sebanyak 1 buah
- Solar Panel sebanyak 1 buah
- Battery shield V3 18650 sebanyak 1 buah
- 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 7. Peta kaki TTGO LORA32 V2.1
Gambar 8. Penyambungan rangkaian: kaki 12 untuk kecepatan angin, kaki 25 untuk arah angin
- #include <HardwareSerial.h>
- HardwareSerial sensor(1);
- unsigned long skr = 0;
- String data;
- void setup() {
- Serial.begin(9600);
- sensor.begin(9600, SERIAL_8N1, 25, 4);
- }
- void loop() {
- if (sensor.available()) {
- data = sensor.readString();
- }
- if (millis() - skr > 5000) {
- skr = millis();
- Serial.println(data.substring(1, 2));
- }
- }
Kode program untuk pembacaan kecepatan dan arah angin:
- #include <HardwareSerial.h>
- HardwareSerial sensor(1);
- volatile byte rpmcount;
- volatile unsigned long last_micros;
- unsigned long timeold;
- unsigned long durasi = 10.0;
- String data;
- int pin_kec = 12;
- float rps;
- float kpj;
- float mps;
- volatile boolean flag = false;
- void ICACHE_RAM_ATTR rpm() {
- flag = true;
- }
- void setup() {
- Serial.begin(9600);
- sensor.begin(9600, SERIAL_8N1, 25, 4);
- pinMode(pin_kec, INPUT_PULLUP);
- digitalWrite(pin_kec, LOW);
- Serial.begin(9600);
- detachInterrupt(digitalPinToInterrupt(pin_kec));
- attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
- rpmcount = 0;
- timeold = 0;
- }
- void loop() {
- if (sensor.available()) {
- data = sensor.readString();
- }
- if (flag == true) {
- if (long(micros() - last_micros) >= 5000) {
- rpmcount++;
- last_micros = micros();
- }
- flag = false;
- }
- if ((millis() - timeold) >= durasi * 1000) {
- detachInterrupt(digitalPinToInterrupt(pin_kec));
- rps = float(rpmcount) / float(durasi);
- mps = ((-0.0181 * (rps * rps)) + (1.3859 * rps) + 1.4055);
- if (mps <= 1.5) mps = 0.0;
- kpj = mps * 3.6;
- Serial.print(data.substring(1, 2));
- Serial.print(",");
- Serial.println(kpj);
- timeold = millis();
- rpmcount = 0;
- attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
- }
- }
Kode program untuk menampilkan data kecepatan dan arah angin di OLED:
- #include <SPI.h>
- #include <LoRa.h>
- #include <Wire.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- #include <HardwareSerial.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);
- HardwareSerial sensor(1);
- volatile byte rpmcount;
- volatile unsigned long last_micros;
- unsigned long timeold;
- unsigned long durasi = 2.0;
- String data;
- int arah = 0;
- int pin_kec = 12;
- float rps;
- float kpj;
- float mps;
- volatile boolean flag = false;
- void ICACHE_RAM_ATTR rpm() {
- flag = true;
- }
- void setup() {
- Serial.begin(9600);
- Wire.begin(OLED_SDA, OLED_SCL);
- if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
- Serial.println(F("SSD1306 allocation failed"));
- for (;;)
- ;
- }
- sensor.begin(9600, SERIAL_8N1, 25, 4);
- pinMode(pin_kec, INPUT_PULLUP);
- digitalWrite(pin_kec, LOW);
- Serial.begin(9600);
- detachInterrupt(digitalPinToInterrupt(pin_kec));
- attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
- rpmcount = 0;
- timeold = 0;
- display.clearDisplay();
- display.setTextColor(WHITE);
- display.setTextSize(1);
- display.setCursor(0, 0);
- display.print("LORA SENDER ");
- display.display();
- Serial.println("LoRa Sender 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.print("LoRa Initializing OK!");
- display.display();
- delay(2000);
- }
- void loop() {
- if (sensor.available()) {
- data = sensor.readString();
- arah = data.substring(1, 2).toInt();
- }
- if (flag == true) {
- if (long(micros() - last_micros) >= 5000) {
- rpmcount++;
- last_micros = micros();
- }
- flag = false;
- }
- if ((millis() - timeold) >= durasi * 1000) {
- detachInterrupt(digitalPinToInterrupt(pin_kec));
- rps = float(rpmcount) / float(durasi);
- mps = ((-0.0181 * (rps * rps)) + (1.3859 * rps) + 1.4055);
- if (mps <= 1.5) mps = 0.0;
- kpj = mps * 3.6;
- LoRa.beginPacket();
- LoRa.print(arah);
- LoRa.print(",");
- LoRa.print(kpj);
- LoRa.endPacket();
- display.clearDisplay();
- display.setTextSize(1);
- display.setCursor(0, 0);
- display.print("Arah Angin: ");
- display.setTextSize(2);
- display.setCursor(0, 10);
- display.print(arah);
- display.setTextSize(1);
- display.setCursor(0, 35);
- display.print("Kecepatan: ");
- display.setTextSize(2);
- display.setCursor(0, 45);
- display.print(kpj);
- display.print(" kpj");
- display.display();
- Serial.print(arah);
- Serial.print(",");
- Serial.println(kpj);
- timeold = millis();
- rpmcount = 0;
- attachInterrupt(digitalPinToInterrupt(pin_kec), rpm, RISING);
- }
- }
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:








.png)