I have 2 problems
the LCD don't show the text "parking is full"
the entrance gate open if total = 0
// include library
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <MFRC522.h>
#define SS_PIN 10 //set pin for RFID
#define RST_PIN 9 //set pin for RFID
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD adress to 0x27 for a 20 chars and 4 line display
int S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0;
int slot = 6;
Servo enterance;
Servo gateexit;
// set the pins that will be used by IR sensors
int IR1 = 8;
int IR2 = 2;
int IR3 = 3;
int IR4 = 4;
int IR5 = 5;
int IR6 = 6;
int IRexit = 7;
void setup()
{
lcd.begin();
lcd.backlight();
Serial.begin(9600); // Initilaize serial communication with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // init MFRC522 card
Serial.println("Approximate your card to the reader...");
Serial.println();
// setting IR sensors
pinMode(IR1, INPUT);
pinMode(IR2, INPUT);
pinMode(IR3, INPUT);
pinMode(IR4, INPUT);
pinMode(IR5, INPUT);
pinMode(IR6, INPUT);
pinMode(IRexit, INPUT);
//setting motors
enterance.attach(A3);
gateexit.attach(A2);
enterance.write(0);
gateexit.write(0);
}
void loop()
{
// Reading sensors
int IR1state = digitalRead(IR1);
int IR2state = digitalRead(IR2);
int IR3state = digitalRead(IR3);
int IR4state = digitalRead(IR4);
int IR5state = digitalRead(IR5);
int IR6state = digitalRead(IR6);
int IRexitstate = digitalRead(IRexit);
lcd.setCursor(0, 0); // set location in LCD
lcd.print(" Parking Systems "); //show the string in the above location
// setting the exit gate , NOTE: the IR sensor used if sense object send low signal to arduino and if not sense high signal
if (IRexitstate == LOW) {
gateexit.write(90); // adjust the angle of the rod of the exit gate to 90 degree
delay(3000);
gateexit.write(0);
} // adjust tge angle of the rod of the exit gate to 0 degree
else {
}
// setting the sensors of the parking spaces and setting LCD with it
lcd.setCursor(0, 1);
if (IR1state == LOW) {
lcd.print("P1:Fill ");
S1 = 1;
}
else {
lcd.print("P1:Empty");
S1 = 0;
}
lcd.setCursor(10, 1);
if (IR2state == LOW) {
lcd.print("P2:Fill ");
S2 = 1;
}
else {
lcd.print("P2:Empty");
S2 = 0;
}
lcd.setCursor(0, 2);
if (IR3state == LOW) {
lcd.print("P3:Fill ");
S3 = 1;
}
else {
lcd.print("P3:Empty");
S3 = 0;
}
lcd.setCursor(10, 2);
if (IR4state == LOW) {
lcd.print("P4:Fill ");
S4 = 1;
}
else {
lcd.print("P4:Empty");
S4 = 0;
}
lcd.setCursor(0, 3);
if (IR5state == LOW) {
lcd.print("P5:Fill ");
S5 = 1;
}
else {
lcd.print("P5:Empty");
S5 = 0;
}
lcd.setCursor(10, 3);
if (IR6state == LOW) {
lcd.print("P6:Fill ");
S6 = 1;
}
else {
lcd.print("P6:Empty");
S6 = 0;
}
int total = slot - (S1 + S2 + S3 + S4 + S5 + S6);
if (!mfrc522.PICC_IsNewCardPresent()) // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
{
return;
}
if (!mfrc522.PICC_ReadCardSerial()) // Select one of the cards
{
return;
}
Serial.print("UID tag :");
String content = "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
Serial.println();
Serial.print("Message : ");
content.toUpperCase();
// check if the card is registed or not
if (content.substring(1) == "D2 36 15 1B" || content.substring(1) == "E3 AE E2 A9" || content.substring(1) == "33 48 CF A9" || content.substring(1) == "93 4B 10 AA" || content.substring(1) == "B3 26 2B AA" || content.substring(1) == "B3 DB C7 A9") {
Serial.println("Authorized access");
Serial.println();
// check if there still space for parking or not
if (total != 0) {
enterance.write(90); // adjust the rod of enterance gate to 90 degree
delay(3000);
enterance.write(0); // adjust the rod of enterance gate to 0 degree
}
else {
lcd.setCursor(0, 0);
lcd.print(" Sorry Parking Full ");
delay(2000);
}
}
else {
Serial.println(" Access denied");
delay(1000);
}
}
i have 2 problems
the LCD don't show the text "parking is full"
the entrance gate open if total = 0
as each park space get full the sensor make value of S = 1
and we have six of them and slot =6
since total =slot - (S1+S2+S3+S4+S5+S6)
when all parking is full total = 0
the entrance gate should not open and show on LCD "parking is full"
We have built a drone controller using C++ and an Arduino ESP32 module. We have achieved connection to a Tello Drone and can control it successfully. However, now we want to connect our controller to a javafx program that receives input and then draws on a canvas in scene builder.
Meanwhile the problem is that we can't seem to connect our controller through PacketSender. We have attached our code, including the previous built that enabled connection with a drone.
The big question is how to send the messages between two programs and initiate our virtual depiction of our drone on a canvas - instead of the actual physical one.
The issue seems to be in case 1, line 190, where we connected controller to actual drone, but now have to write up a new connection somehow.
#include <Arduino.h>
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "OnePlus 7 Pro";
const char * password = "hej12345";
//Connect button variables (Command)
int inPinLand = 18;
int valLand = 0;
//Ultra sonic sensor variables
#define trigPin 2
#define echoPin 21
//Land button variables (Land)
int inPin = 25;
int val = 0;
//Instantiate specific drone
const char * networkName = "TELLO-59F484";
const char * networkPswd = "";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const char * udpAddress = "10.60.0.227";
const int udpPort = 7000;
boolean connected = false;
char fromTello[256];
unsigned long timer;
//static const byte glyph[] = { B00010000, B00110100, B00110000, B00110100, B00010000 };
//static PCD8544 lcd;
uint8_t state = 0;
//Controller movement variables
int pitch = 0;
int roll = 0;
int yaw = 0;
int throttle = 0;
char cmd[256];
AsyncUDP udp;
void setup() {
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while (1) {
delay(1000);
}
}
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(inPin, INPUT);
pinMode(inPinLand, INPUT);
//LCD screen initialization
//lcd.begin(84, 48);
Serial.begin(9600);
//pinMode(trigPin, OUTPUT);
//pinMode(echoPin, INPUT);
//pinMode(BL, OUTPUT);
//digitalWrite(BL, HIGH);
if (udp.listen(7000)) {
Serial.print("UDP Listening on IP: ");
Serial.println(WiFi.localIP());
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()
? "Broadcast"
: packet.isMulticast() ? "Multicast" : "Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
// reply to the client/sender
packet.printf("Got %u bytes of data", packet.length());
});
}
// Send unicast
// udp.print("Hello Server!");
// udp.
}
//WiFi connection function
void connectToWiFi(const char * ssid, const char * pwd) {
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//Drone connection function
void TelloCommand(char *cmd) {
//only send data when connected
if (connected) {
//Send a packet
//udp.beginPacket(udpAddress, udpPort); OUTDATED has new name with ASync
udp.printf(cmd);
//udp.endPacket(); OUTDATED has new name with ASync
Serial.printf("Send [%s] to Tello.\n", cmd);
}
}
void sendMessage(String msg){
udp.writeTo((const uint8_t *)msg.c_str(), msg.length(),
IPAddress(169, 254, 107, 16), 4000);
}
void loop() {
delay(5000);
// Send broadcast on port 4000
udp.broadcastTo("Anyone here?", 4000);
// Serial.println("waiting for udp message...");
int x = 100;
int y = 100;
sendMessage("init " + String(x) + " " + String(y));
}
void loop() {
long duration, distance;
val = digitalRead(inPin); // read input value
//Ultra sonic sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
//LCD screen line 2
// lcd.setCursor(0, 1);
// lcd.print(distance, DEC);
//State machine that connects the drone to WiFi and the controller
switch (state)
{
case 0: //Idle not connected
//LCD screen line 1
//lcd.setCursor(0, 0);
//lcd.print("Controller");
if (val == HIGH)
{
state = 1;
connectToWiFi(networkName, networkPswd);
timer = millis() + 5000;
}
break;
case 1: //Trying to connect
if (WiFi.status() == WL_CONNECTED)
{
Serial.print("Connected to: ");
Serial.println(networkName);
udp.begin(WiFi.localIP(), udpPort);
connected = true;
TelloCommand("command");
timer = millis() + 2000;
state = 2;
}
if (millis() > timer)
{
state = 0;
}
break;
case 2: //Connected on ground
//lcd.setCursor(0, 0);
//lcd.print("Connected ");
if (WiFi.status() != WL_CONNECTED)
{
WiFi.disconnect(true);
Serial.println("Disconnected");
state = 0;
}
if (distance < 10)
{
TelloCommand("takeoff");
timer = millis() + 1000;
state = 3;
Serial.println("takeoff");
}
break;
case 3: //In air
//lcd.setCursor(0, 0);
//lcd.print("In air ");
if (millis() > timer)
{
timer = millis() + 20;
pitch = map(analogRead(34) - 1890, -2000, 2000, -100, 100);
roll = map(analogRead(35) - 1910, -2000, 2000, -100, 100);
throttle = map(analogRead(33) - 1910, -2000, 2000, -100, 100);
yaw = map(analogRead(32) - 1910, -2000, 2000, -100, 100);
sprintf(cmd, "rc %d %d %d %d", roll, pitch, throttle, yaw);
TelloCommand(cmd);
}
if (val == HIGH) {
TelloCommand("land");
timer = millis() + 1000;
state = 0;
Serial.println("land");
}
break;
}
delay(200);
}
I'm trying to execute following source on my RC transmitter and receiver which uses NRF24 module. Today i uploaded same sketch as i did half year ago and it stopped receiving any data from transmitter, nothing is printed in DEBUG_PRINT sections.
On transmitter NRF24 is connected to 7, 8.
On receiver NRF24 is connected to 9, 10.
Wiring checked 7 times, correct, power supply of the receiver is 7.4V to the VIN, power supply for the transmitter is USB source.
Running on the arduino nano.
Source for transmitter is:
// Flash for self-diy NRF24lo* transmiter controller.
// 6 buttons, 4-way sticks, based on CX-10c controller.
#include <EEPROM.h>
#include <SPI.h>
#include "RF24.h"
#define DEBUG_PRINT
// #define DEBUG_PRINT_RAW
#ifdef DEBUG_PRINT
#include <printf.h>
#endif
// IO mappings
#define STICK0 A3
#define STICK1 A2
#define STICK2 A0
#define STICK3 A1
#define BTN0 3
#define BTN1 6
#define BTN2 5
#define BTN3 4
#define BTN4 9
#define BTN5 A4
#define STLED 2
// Optional moddings
#define BTN_LONG_PRESS 1000
#define LED_ST_OFF 0
#define LED_ST_CONST 1
#define LED_ST_FLASH 2
#define LED_ST_FAST_FLASH 3
#define LED_ST_FLASH_TIME 250
#define LED_ST_FAST_FLASH_TIME 100
#define LED_POWER 150
// Package types
#define PACKAGE_STICKS 3
#define PACKAGE_BUTTON 5
#define PACKAGE_PING 7
#define PACKAGE_TIMEOUT 100
// Amount of packages should be dropped sequently to detect disconnect
#define TX_DROP_EDGE 16
// Long press stick 0 to start calibration, long press to stop
// Struct with min/max calibration values
struct STICK_CALIBRATION {
int stmx[4];
int stmn[4];
};
// Struct with info of button presses
struct BTN_STATE {
int press[6];
unsigned long time[6];
// Used in long press to avoid multiple pressing
int acted[6];
};
// Struct with state of flashing/idle/working LED
// FLASH --> CONST/OFF
// FAST_FLASH --> CONST/OFF
struct LED_STATE {
// Previous type (for FLASH return to OFF/CONST state)
int ptype;
// Type of operation
int type;
// ON/OFF
int state;
// Time since action
unsigned long time;
// Count of flashes
int count;
};
// Sender package type.
// Contains type and values for button or values for sticks
struct Package {
int type;
union {
struct {
int number;
int lpress;
int dummy[2];
} button;
struct {
int sticks[4];
} sticks;
} data;
};
// Info of sticks calibration
STICK_CALIBRATION calibration;
bool calibration_mode = 0;
int sticks[4];
// When entering lock mode, stick data is not updating from input
bool lock_mode = 0;
// info of buttons states
BTN_STATE buttons;
LED_STATE led_state;
// Use NRF24lo1 transmitter on pins 7, 8
RF24 radio(7, 8);
byte addresses[][6] = { "TRAAA", "REEEE" };
// Amount of sequently dropped packages. Used to detect disconnect
int tx_dropped = 0;
// Used to prevent longpress repeat
// On long press button could be used as sticky press function,
// to avoid button sticking and long press act once during while push down,
// use this function to mark button as acted
void btn_act(int nubmer);
// Called on button press/longpress
void btn_action(int number, int lpress);
// Set led ON/OFF with change of state flag
void led_set_state(int state);
// Set led action type (FLAST, CONST, e.t.c.)
void led_set(int type, int count);
// Sends single package with given amount of attempts.
// Allows waiting for responce of receiver. The response should be 0.
// Returns 1 on success, 0 on failture.
int send_package(byte* pack, int size);
void setup() {
#ifdef DEBUG_PRINT
Serial.begin(115200);
#endif
// Set up transmitter
radio.begin();
radio.setChannel(77);
radio.enableAckPayload();
radio.setPALevel(RF24_PA_MAX);
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1, addresses[0]);
#ifdef DEBUG_PRINT
printf_begin();
radio.printDetails();
#endif
// Read calibration values
byte* cal_struct = (byte*) &calibration;
for (int i = 0; i < sizeof(STICK_CALIBRATION); ++i)
cal_struct[i] = EEPROM.read(i);
#ifdef DEBUG_PRINT
Serial.println("CALIBRATION: ");
for (int i = 0; i < 4; ++i) {
Serial.print('(');
Serial.print(calibration.stmn[i]);
Serial.print(", ");
Serial.print(calibration.stmx[i]);
Serial.print(") ");
}
Serial.println();
#endif
buttons = {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}};
// Clear LED state
led_state.ptype = 0;
led_state.type = 0;
led_state.state = 0;
led_state.time = 0;
led_state.count = 0;
// Prepare pinout
pinMode(STLED, OUTPUT);
pinMode(STICK0, INPUT_PULLUP);
pinMode(STICK1, INPUT_PULLUP);
pinMode(STICK2, INPUT_PULLUP);
pinMode(STICK3, INPUT_PULLUP);
pinMode(BTN0, INPUT_PULLUP);
pinMode(BTN1, INPUT_PULLUP);
pinMode(BTN2, INPUT_PULLUP);
pinMode(BTN3, INPUT_PULLUP);
pinMode(BTN4, INPUT_PULLUP);
pinMode(BTN5, INPUT_PULLUP);
}
void loop() {
// Read sticks & map to calibration
if (!lock_mode) {
sticks[0] = analogRead(STICK0);
sticks[1] = analogRead(STICK1);
sticks[2] = 1024 - analogRead(STICK2);
sticks[3] = 1024 - analogRead(STICK3);
}
// Read stick buttons
int rbtn[6];
rbtn[0] = !digitalRead(BTN0);
rbtn[1] = !digitalRead(BTN1);
// read optional buttons
rbtn[2] = !digitalRead(BTN2);
rbtn[3] = !digitalRead(BTN3);
rbtn[4] = !digitalRead(BTN4);
rbtn[5] = !digitalRead(BTN5);
#ifdef DEBUG_PRINT
#ifdef DEBUG_PRINT_RAW
// Debug out
Serial.print(sticks[0]); Serial.print(' ');
Serial.print(sticks[1]); Serial.print(' ');
Serial.print(sticks[2]); Serial.print(' ');
Serial.print(sticks[3]); Serial.print(' ');
Serial.print(rbtn[0]); Serial.print(' ');
Serial.print(rbtn[1]); Serial.print(' ');
Serial.print(rbtn[2]); Serial.print(' ');
Serial.print(rbtn[3]); Serial.print(' ');
Serial.print(rbtn[4]); Serial.print(' ');
Serial.print(rbtn[5]); Serial.print(' ');
Serial.println();
#endif
#endif
// Map to calibration
if (!calibration_mode && !lock_mode) {
sticks[0] = map(sticks[0], calibration.stmn[0], calibration.stmx[0], 0, 1023);
sticks[1] = map(sticks[1], calibration.stmn[1], calibration.stmx[1], 0, 1023);
sticks[2] = map(sticks[2], calibration.stmn[2], calibration.stmx[2], 0, 1023);
sticks[3] = map(sticks[3], calibration.stmn[3], calibration.stmx[3], 0, 1023);
}
// Check buttons states and update timings
for (int i = 0; i < 6; ++i) {
if (buttons.press[i] && !rbtn[i]) { // Button released
if (!buttons.acted[i])
btn_action(i, (millis() - buttons.time[i]) > BTN_LONG_PRESS);
buttons.press[i] = 0;
buttons.time[i] = 0;
} else if (buttons.press[i]) { // Button keeps down
if ((millis() - buttons.time[i]) > BTN_LONG_PRESS && !buttons.acted[i]) { // Toggle long press
btn_action(i, 1);
// buttons.press[i] = 0;
buttons.time[i] = 0;
}
} else if (rbtn[i]) { // Button pressed
buttons.press[i] = 1;
buttons.acted[i] = 0;
buttons.time[i] = millis();
}
}
// Update LED
if (led_state.type == LED_ST_FLASH && (led_state.time + LED_ST_FLASH_TIME) < millis()
||
led_state.type == LED_ST_FAST_FLASH && (led_state.time + LED_ST_FAST_FLASH_TIME) < millis()) { // Flash period done
if (!led_state.state) { // Count cycle as finished, try to begin another one
--led_state.count;
if (led_state.count <= 0) { // Flashing cycles is done
led_state.type = led_state.ptype;
led_set_state(led_state.type == LED_ST_CONST);
} else { // Turn led ON again, begin next flash cycle
led_state.time = millis();
led_set_state(1);
}
} else { // Just turn the led OFF
led_state.time = millis();
led_set_state(0);
}
}
// Update led flashing
if (led_state.type != LED_ST_FLASH && led_state.type != LED_ST_FAST_FLASH) {
if (calibration_mode)
led_set(LED_ST_FAST_FLASH, 4);
else {
// Update led lighting
if (lock_mode)
led_set(LED_ST_CONST, 0);
else
led_set(LED_ST_OFF, 0);
}
}
// If !paired
if (calibration_mode) {
for (int i = 0; i < 4; ++i) {
if (calibration.stmn[i] > sticks[i])
calibration.stmn[i] = sticks[i];
if (calibration.stmx[i] < sticks[i])
calibration.stmx[i] = sticks[i];
}
} else {
// Sending package with sticks
Package pack;
pack.type = PACKAGE_STICKS;
pack.data.sticks.sticks[0] = sticks[0];
pack.data.sticks.sticks[1] = sticks[1];
pack.data.sticks.sticks[2] = sticks[2];
pack.data.sticks.sticks[3] = sticks[3];
bool result = send_package((byte*) &pack, sizeof(Package));
if (!result) {
if (tx_dropped > TX_DROP_EDGE && led_state.type != LED_ST_FLASH && led_state.type != LED_ST_FAST_FLASH)
led_set(LED_ST_FLASH, 4);
#ifdef DEBUG_PRINT
Serial.println("TX failed");
#endif
}
}
}
int send_package(byte* pack, int size) {
if (!radio.write(pack, size)) {
++tx_dropped;
return 0;
} else {
byte payload;
if (radio.isAckPayloadAvailable()) {
radio.read(&payload, sizeof(byte));
tx_dropped = 0;
return 1;
}
++tx_dropped;
return 0;
}
};
void led_set_state(int state) {
if (led_state.state && !state) {
digitalWrite(STLED, 0);
led_state.state = !led_state.state;
} else if (!led_state.state && state) {
analogWrite(STLED, LED_POWER);
led_state.state = !led_state.state;
}
};
void led_set(int type, int count) {
if (type == LED_ST_CONST || type == LED_ST_OFF) {
led_set_state(type == LED_ST_CONST);
led_state.type = type;
} else {
// if was flashing --> rewrite
// if was constant --> move type to ptype & do flashing
if (led_state.type == LED_ST_CONST || led_state.type == LED_ST_OFF)
led_state.ptype = led_state.type;
led_state.type = type;
led_state.count = count;
led_state.time = millis();
led_set_state(1);
}
};
void btn_act(int number) {
buttons.acted[number] = 1;
};
// Override calls for button presses
void btn_action(int number, int lpress) {
#ifdef DEBUG_PRINT
Serial.print("Press for "); Serial.println(number);
#endif
switch(number) {
// calibration
case 0: {
// press = ?
// Lpress = calibration mode
if (lpress) {
if (calibration_mode && !lock_mode) {
// Write calibration values
byte* cal_struct = (byte*) &calibration;
for (int i = 0; i < sizeof(STICK_CALIBRATION); ++i)
EEPROM.write(i, cal_struct[i]);
calibration_mode = 0;
#ifdef DEBUG_PRINT
Serial.println("NEW CALIBRATION: ");
for (int i = 0; i < 4; ++i) {
Serial.print('(');
Serial.print(calibration.stmn[i]);
Serial.print(", ");
Serial.print(calibration.stmx[i]);
Serial.print(") ");
}
Serial.println();
#endif
} else {
for (int i = 0; i < 4; ++i) {
calibration.stmn[i] = 1024;
calibration.stmx[i] = 0;
}
calibration_mode = 1;
}
}
break;
}
case 1: {
// press = ?
// Lpress = lock mode
if (lpress) {
lock_mode = !lock_mode;
}
break;
}
}
led_set(LED_ST_FAST_FLASH, 2);
btn_act(number);
Package pack;
pack.type = PACKAGE_BUTTON;
pack.data.button.number = number;
pack.data.button.lpress = lpress;
bool result = send_package((byte*) &pack, sizeof(Package));
#ifdef DEBUG_PRINT
if (!result)
Serial.println("Button TX failed");
#endif
};
Source for receiver is:
// Flash for self-diy NRF24lo* receiver controller.
// 6 buttons, 4-way sticks.
#include <Servo.h>
#include <SPI.h>
#include "RF24.h"
#define DEBUG_PRINT
#ifdef DEBUG_PRINT
#include <printf.h>
#endif
// IO mappings
#define CONNECT_0 2
#define CONNECT_1 3
#define CONNECT_2 4
#define CONNECT_3 5
#define CONNECT_4 6
#define CONNECT_5 7
#define CONNECT_6 8
#define CONNECT_A0 A0
#define CONNECT_A1 A1
#define CONNECT_A2 A2
#define CONNECT_A3 A3
#define CONNECT_A4 A4
#define CONNECT_A5 A5
// A6, A7 on nano are only analog input
#define CONNECT_A6 A6
#define CONNECT_A7 A7
// Inverters for sticks
#define INVERT_STICK0 0
#define INVERT_STICK1 0
#define INVERT_STICK2 0
#define INVERT_STICK3 0
// Mappings for sticks
#define SERVO_MAP_STICK0 0, 180
#define SERVO_MAP_STICK1 0, 180
#define SERVO_MAP_STICK2 0, 180
#define SERVO_MAP_STICK3 60, 120
#define ANALOG_MAP_STICK0 0, 255
#define ANALOG_MAP_STICK1 0, 255
#define ANALOG_MAP_STICK2 0, 255
#define ANALOG_MAP_STICK3 0, 255
// Optional moddings
// Package types
#define PACKAGE_STICKS 3
#define PACKAGE_BUTTON 5
#define PACKAGE_PING 7
// Used to detect disconnect from the controller
#define CONNECTION_TIMEOUT 100
// Mpdes for output of the motor
// #define MODE_2_DIGITAL_1_ANALOG
#define MODE_2_ANALOG
// Receiver package struct.
// Contains type and values for button or values for sticks
struct Package {
int type;
union {
struct {
int number;
int lpress;
// Used to complete size of the package.
// Without it, payload is not sending for sticks.
int dummy[2];
} button;
struct {
int sticks[4];
} sticks;
} data;
};
// Describes state of a single buttons on controller
// Single press -> 1
// Second press -> 0
struct Button {
bool state;
bool lstate;
};
// Use NRF24lo1 transmitter on pins 7, 8
RF24 radio(9, 10);
byte addresses[][6] = { "TRAAA", "REEEE" };
// Used to detect timed disconnection from the controller
unsigned long last_receive_time;
bool disconnected;
// Servos mapped to sticks
Servo servo[4];
// Buttons states
Button buttons[6];
// Called on connection restored after drop
void on_connection();
// Called on connection dropped
void on_disconnection();
// Called on button state received
void button_action(int button, int lpress);
// Called on sticks state received
void sticks_action(int sticks[4]);
void setPWMNanofrequency(int freq) {
TCCR2B = TCCR2B & 0b11111000 | freq;
TCCR1B = TCCR1B & 0b11111000 | freq;
}
void setup() {
#ifdef DEBUG_PRINT
Serial.begin(115200);
#endif
// Set up receiver
radio.begin();
radio.setChannel(77);
//radio.setAutoAck(1);
//radio.setRetries(0, 8);
radio.enableAckPayload();
radio.setPALevel(RF24_PA_MAX);
//radio.setCRCLength(RF24_CRC_8);
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1, addresses[1]);
#ifdef DEBUG_PRINT
// Debugger output
printf_begin();
radio.printDetails();
#endif
radio.startListening();
// Init buttons with 0
buttons[0] = { 0, 0 };
buttons[1] = { 0, 0 };
buttons[2] = { 0, 0 };
buttons[3] = { 0, 0 };
buttons[4] = { 0, 0 };
buttons[5] = { 0, 0 };
// Set up pinout
pinMode(CONNECT_0, OUTPUT);
pinMode(CONNECT_2, OUTPUT);
pinMode(CONNECT_3, OUTPUT);
pinMode(CONNECT_4, OUTPUT);
pinMode(CONNECT_5, OUTPUT);
pinMode(CONNECT_6, OUTPUT);
pinMode(CONNECT_A0, OUTPUT);
pinMode(CONNECT_A1, OUTPUT);
pinMode(CONNECT_A2, OUTPUT);
pinMode(CONNECT_A3, OUTPUT);
pinMode(CONNECT_A4, OUTPUT);
pinMode(CONNECT_A5, OUTPUT);
pinMode(CONNECT_A6, INPUT);
pinMode(CONNECT_A7, INPUT);
// setPWMNanofrequency(0x02);
// Set up servos
servo[0].attach(CONNECT_A4); // Remapped servos to leave three PWM pins
servo[1].attach(CONNECT_A5);
servo[2].attach(CONNECT_5);
servo[3].attach(CONNECT_6);
// Clear disconnect trigger
last_receive_time = millis();
disconnected = 0;
// Reset outputs
digitalWrite(CONNECT_0, LOW);
digitalWrite(CONNECT_2, LOW);
digitalWrite(CONNECT_3, LOW);
digitalWrite(CONNECT_4, LOW);
digitalWrite(CONNECT_5, LOW);
digitalWrite(CONNECT_6, LOW);
digitalWrite(CONNECT_A0, LOW);
digitalWrite(CONNECT_A1, LOW);
digitalWrite(CONNECT_A2, LOW);
digitalWrite(CONNECT_A3, LOW);
digitalWrite(CONNECT_A4, LOW);
digitalWrite(CONNECT_A5, LOW);
// digitalWrite(CONNECT_A6, LOW);
// digitalWrite(CONNECT_A7, LOW);
}
void loop() {
byte payload = 13;
radio.writeAckPayload(1, &payload, sizeof(byte));
if (radio.available()) {
Package pack;
radio.read((byte*) &pack, sizeof(Package));
// Update trigger
last_receive_time = millis();
if (disconnected)
on_connection();
disconnected = 0;
switch(pack.type) {
case PACKAGE_STICKS: {
#ifdef DEBUG_PRINT
Serial.print(pack.data.sticks.sticks[0]); Serial.print(' ');
Serial.print(pack.data.sticks.sticks[1]); Serial.print(' ');
Serial.print(pack.data.sticks.sticks[2]); Serial.print(' ');
Serial.print(pack.data.sticks.sticks[3]); Serial.println();
#endif
if (INVERT_STICK0) pack.data.sticks.sticks[0] = 1024 - pack.data.sticks.sticks[0];
if (INVERT_STICK1) pack.data.sticks.sticks[1] = 1024 - pack.data.sticks.sticks[1];
if (INVERT_STICK2) pack.data.sticks.sticks[2] = 1024 - pack.data.sticks.sticks[2];
if (INVERT_STICK3) pack.data.sticks.sticks[3] = 1024 - pack.data.sticks.sticks[3];
int ssticks[4];
ssticks[0] = map(pack.data.sticks.sticks[0], 0, 1023, SERVO_MAP_STICK0);
ssticks[1] = map(pack.data.sticks.sticks[1], 0, 1023, SERVO_MAP_STICK1);
ssticks[2] = map(pack.data.sticks.sticks[2], 0, 1023, SERVO_MAP_STICK2);
ssticks[3] = map(pack.data.sticks.sticks[3], 0, 1023, SERVO_MAP_STICK3);
int asticks[4];
asticks[0] = map(pack.data.sticks.sticks[0], 0, 1023, ANALOG_MAP_STICK0);
asticks[1] = map(pack.data.sticks.sticks[1], 0, 1023, ANALOG_MAP_STICK1);
asticks[2] = map(pack.data.sticks.sticks[2], 0, 1023, ANALOG_MAP_STICK2);
asticks[3] = map(pack.data.sticks.sticks[3], 0, 1023, ANALOG_MAP_STICK3);
#ifdef DEBUG_PRINT
Serial.print("Servo data: ");
Serial.print(ssticks[0]); Serial.print(' ');
Serial.print(ssticks[1]); Serial.print(' ');
Serial.print(ssticks[2]); Serial.print(' ');
Serial.print(ssticks[3]); Serial.println();
Serial.print("Analog data: ");
Serial.print(asticks[0]); Serial.print(' ');
Serial.print(asticks[1]); Serial.print(' ');
Serial.print(asticks[2]); Serial.print(' ');
Serial.print(asticks[3]); Serial.println();
#endif
sticks_action(pack.data.sticks.sticks, ssticks, asticks);
break;
}
case PACKAGE_BUTTON: {
#ifdef DEBUG_PRINT
Serial.print(pack.data.button.number); Serial.print(' ');
Serial.print(pack.data.button.lpress); Serial.println();
#endif
// Update states of the buttons
if (pack.data.button.lpress)
buttons[pack.data.button.number].lstate = !buttons[pack.data.button.number].lstate;
else
buttons[pack.data.button.number].state = !buttons[pack.data.button.number].state;
button_action(pack.data.button.number, pack.data.button.lpress);
break;
}
}
} else if (!disconnected && millis() - last_receive_time > CONNECTION_TIMEOUT) {
disconnected = 1;
on_disconnection();
}
}
void on_connection() {
};
void on_disconnection() {
// servo[0].write(0);
// servo[1].write(0);
// servo[2].write(0);
// servo[3].write(0);
// analogWrite(CONNECT_A0, 0);
// analogWrite(CONNECT_A1, 0);
// analogWrite(CONNECT_A2, 0);
// analogWrite(CONNECT_A3, 0);
#ifdef MODE_2_DIGITAL_1_ANALOG
digitalWrite(CONNECT_1, LOW);
digitalWrite(CONNECT_2, LOW);
digitalWrite(CONNECT_3, LOW);
#endif
#ifdef MODE_2_ANALOG
digitalWrite(CONNECT_3, LOW);
digitalWrite(CONNECT_4, LOW);
digitalWrite(CONNECT_0, LOW);
#endif
};
void button_action(int button, int lpress) {
switch (button) {
case 0:
case 1:
break;
case 2: {
digitalWrite(CONNECT_A0, buttons[button].state);
break;
}
case 3: {
digitalWrite(CONNECT_A1, buttons[button].state);
break;
}
case 4: {
digitalWrite(CONNECT_A2, buttons[button].state);
break;
}
case 5: {
digitalWrite(CONNECT_A3, buttons[button].state);
break;
}
}
};
void sticks_action(int sticks[4], int ssticks[4], int asticks[4]) {
servo[0].write(ssticks[0]);
servo[1].write(ssticks[1]);
servo[2].write(ssticks[2]);
servo[3].write(ssticks[3]);
// analogWrite(CONNECT_A0, asticks[0]);
// analogWrite(CONNECT_A1, asticks[1]);
// analogWrite(CONNECT_A2, asticks[2]);
// analogWrite(CONNECT_A3, asticks[3]);
// Control H-Bridge over 3, 4 outputs with right stick
int value = (sticks[2] > 500) ? (sticks[2] - 500) : (sticks[2] < 480) ? (480 - sticks[2]) : (0);
if (value < 500)
value = map(value, 0, 480, 0, 255);
else
value = map(value, 0, 1023 - 500, 0, 255);
value = (value > 255) ? 255 : (value < 0) ? 0 : value;
// connecting 2 digital pins as HIGH,LOW / LOW,HIGH and analog as speed value (used in bts79603 bridge)
#ifdef MODE_2_DIGITAL_1_ANALOG
if (sticks[2] > 500) {
digitalWrite(CONNECT_1, HIGH);
digitalWrite(CONNECT_2, LOW);
analogWrite(CONNECT_3, value);
} else if (sticks[2] < 480) {
digitalWrite(CONNECT_1, LOW);
digitalWrite(CONNECT_2, HIGH);
analogWrite(CONNECT_3, value);
} else {
digitalWrite(CONNECT_1, LOW);
digitalWrite(CONNECT_2, LOW);
analogWrite(CONNECT_3, 0);
}
#endif
// connecting 2 analog pins to simple H-Bridge
#ifdef MODE_2_ANALOG
analogWrite(CONNECT_3, sticks[2] > 500 ? value : 0);
analogWrite(CONNECT_4, sticks[2] < 480 ? value : 0);
analogWrite(CONNECT_0, sticks[2] > 500 || sticks[2] < 480);
#endif
};
Transmitter printDetails output:
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x4141415254 0x4545454552
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x4141415254
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4d
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
Receiver printDetails output:
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x4545454552 0x4141415254
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x4545454552
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x02
RF_CH = 0x4d
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
Code used
Following code on receiver caused IO break.
pinMode(CONNECT_A6, INPUT);
pinMode(CONNECT_A7, INPUT);
A6, A7 pins DOES NOT support mode change and this issue made NRF24 connection to fail.
I am trying to get voltage values from my master to my slave but only the voltage from Pin3 is being sent over and not my values from pin 4. I am new to coding so please make your solution very "jargon-less." If you could provide me with an example then it will be greatly appreciated.
MASTER CODE:
void pin3() {
Wire.beginTransmission(0x08);
int val2 = analogRead(twosensorpin);
float volts2 = (val2 / 1023.0) * refvoltage;
voltage = String(volts2);
char volt2[5];
voltage.toCharArray(volt2, 5);
Serial.print("The voltage are pin 2 is ");
Serial.println(voltage);
Wire.write(volt2);
Wire.endTransmission();
}
void pin4() {
Wire.beginTransmission(0x08);
int val3 = analogRead(threesensorpin);
float volts3 = (val3 / 1023.0) * refvoltage;
voltage2 = String(volts3);
char volt3[5];
voltage.toCharArray(volt3, 5);
Serial.print("The voltage are pin 3 is ");
Serial.println(voltage2);
Wire.write(volt3);
Wire.endTransmission();
}
SLAVE CODE:
#include <Wire.h>
#define SLAVE_ADDRESS 0X08
String q;
String r = "3.20";
// name the motor control pins
#define PWMa 7
#define PWMb 5
#define PWMc 8
#define PWMd 6
void setup() {
// configure the motor control pins as outputs
pinMode(PWMa, OUTPUT);
pinMode(PWMb, OUTPUT);
pinMode(PWMc, OUTPUT);
pinMode(PWMd, OUTPUT);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
//Wire.onRequest(requestEvent);
Serial.begin(9600);
}
void loop() {}
void receiveEvent() {
q = "";
while (Wire.available()) {
char c = Wire.read();
q += c;
}
do {
if (q < r) {
Serial.print("The value coming from pin 2 is ");
Serial.println(q);
digitalWrite(PWMa, LOW);
digitalWrite(PWMb, HIGH);
digitalWrite(PWMc, LOW);
digitalWrite(PWMd, HIGH);
//delay(500);
}
} while (Wire.available());
do {
if (q > r) {
digitalWrite(PWMa, HIGH);
digitalWrite(PWMb, LOW);
digitalWrite(PWMc, HIGH);
digitalWrite(PWMd, LOW);
}
} while (Wire.available());
As Edd said you should show us some output.
But assuming you're trying to compare the incoming data to 3.20 as a numerical value, the following code will do the job.
Master
float send_i2c(int val){
float volts = (val / 1023.0) * refvoltage;
char v[5];
String(volts).toCharArray(v, 5);
Wire.beginTransmission(0x08);
Wire.write(v);
Wire.endTransmission();
return volts;
}
void pin3(){
Serial.println("Pin3 val : " + String(send_i2c(analogRead(twosensorpin))));
}
void pin4(){
Serial.println("Pin4 val : " + String(send_i2c(analogRead(threesensorpin))));
}
Slave
#include <Wire.h>
#define SLAVE_ADDRESS 0X08
#define R 3.20
String q;
// name the motor control pins
#define PWMa 7
#define PWMb 5
#define PWMc 8
#define PWMd 6
void setup() {
// configure the motor control pins as outputs
pinMode(PWMa, OUTPUT);
pinMode(PWMb, OUTPUT);
pinMode(PWMc, OUTPUT);
pinMode(PWMd, OUTPUT);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
}
void loop() {}
void receiveEvent(int a) {
int num = 0;
while (Wire.available())
q += Wire.read();
num = q.toInt();
Serial.print("The value: ");
Serial.println(q);
digitalWrite(PWMa, (num < R) ? LOW : HIGH);
digitalWrite(PWMb, (num < R) ? HIGH : LOW);
digitalWrite(PWMc, (num < R) ? LOW : HIGH);
digitalWrite(PWMd, (num < R) ? HIGH : LOW);
q = "";
}
But again you should consider your way of controlling your GPIO outputs.
You've done quite a lot of mistakes. Check this page to get more idea about Strings. And this page for Wire transmission.
For a school project, I'm using an Arduino Uno together with a Parallax RFID, a LCD screen and an esp8226-wifi module.
I'm trying to compare the scanned tag with the tags in the database and send the name of the tag owner to a terminal in the Blynk app. Everything works just fine until I put in the function that compares the tags. If I do that, everything stops working, even the code in the setup() part. How can I fix this?
I think the problem has somehing to do with the strcmp.
/* Libraries that need to be manually installed:
Blynk libraries: https://github.com/blynkkk/blynk-library/releases/download/v0.5.0/Blynk_Release_v0.5.0.zip
LiquidCrystal_I2C library: https://cdn.instructables.com/ORIG/FVH/K8OQ/J8UH0B9U/FVHK8OQJ8UH0B9U.zip
*/
#define BLYNK_PRINT Serial
#include <SoftwareSerial.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//Setting up the Blynk wifi connection
#define ESP8266_BAUD 9600
char auth[] = "87b00838cd834e4e87a0422265cc7a9e";
char ssid[] = "bbox2-56b2";
char pass[] = "91C2D797F6";
//Setting up the virtual pins
WidgetTerminal terminal(V1);
BLYNK_WRITE(V1){}
//Setting up the RFID
#define RFIDEnablePin 8
#define RFIDSerialRate 2400
String RFIDTAG=""; //Holds the RFID Code read from a tag
String DisplayTAG = ""; //Holds the last displayed RFID Tag
//Setting up the LCD
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//Setting up the serial connection
SoftwareSerial EspSerial(2, 3);
ESP8266 wifi(&EspSerial);
void setup()
{
//Serial communication
Serial.begin(RFIDSerialRate);
EspSerial.begin(ESP8266_BAUD);
Serial.begin(RFIDSerialRate);
delay(10);
//Blynk setup
Blynk.begin(auth, wifi, ssid, pass);
//LCD setup
lcd.begin(16,2);//16 kolommen, 2 rijen
lcd.backlight();
//RFID setup
pinMode(RFIDEnablePin,OUTPUT);
digitalWrite(RFIDEnablePin, LOW);
terminal.println("Terminal printing succesfull");
terminal.flush();
}
void loop()
{
if(Serial.available() > 0)
{
ReadSerial(RFIDTAG);
}
if(DisplayTAG!=RFIDTAG)
{
DisplayTAG=RFIDTAG;
// PROBLEM STARTS HERE
//Tag database
char tags[10][10] = {"6196", "6753", "5655", "69EC", "9FFC"};
char owners[10][30] = {"per1", "per2", "per3", "per4", "per5"};
int i = 0;
int j = 0;
int ownerLength = 0;
char lastTag[10];
RFIDTAG.toCharArray(lastTag, 10);
while (i < 10)
{
if (strcmp(tags[i], lastTag) == 0)
{
ownerLength = strlen(owners[i]);
while (j < ownerLength)
{
terminal.print(owners[i][j]);
}
terminal.println("has entered the parking\n\r");
terminal.flush();
break;
}
i++;
}
i = 0;
j = 0;
//PROBLEM ENDS HERE
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Last tag:");
lcd.setCursor(0,1);
lcd.print(RFIDTAG);
digitalWrite(RFIDEnablePin, HIGH);
delay(1000);
digitalWrite(RFIDEnablePin, LOW);
}
Blynk.run();
}
//Function for reading the tag
void ReadSerial(String &ReadTagString)
{
int bytesread = 0;
int val = 0;
char code[10];
String TagCode="";
if(Serial.available() > 0)
{
if((val = Serial.read()) == 10)
{
bytesread = 0;
while(bytesread<10) // Reads the tag code
{
if( Serial.available() > 0)
{
val = Serial.read();
if((val == 10)||(val == 13)) // If header or stop bytes before the 10 digit reading
{
break; // Stop reading
}
code[bytesread] = val; // Add the digit
bytesread++; // Ready to read next digit
}
}
if(bytesread == 10) // If 10 digit read is complete
{
for(int x=6;x<10;x++) //Copy the Chars to a String
{
TagCode += code[x];
}
ReadTagString = TagCode; //Returns the tag ID
while(Serial.available() > 0) //Burn off any characters still in the buffer
{
Serial.read();
}
}
bytesread = 0;
TagCode="";
}
}
}