Hi All
I have some code I've grabbed for WiFi and I'm changing the data being sent.
I've successfully changed the struct command to what I now want it to be, this is on the Master.
Next I need to send this data over wifi, I have commented out the line I'm struggling with as I don't understand it and how to change it to now be correct.
Could somebody please explain this:-
UDP.write((char*)&send_data,sizeof(struct led_command));
It is writing data to UDP, I understand the last bit where it sends the length of the string.
I do not understand the char* bit and what it does and more importantly how I change it for my new struct.
I am wanting to send 2 values, which are in the new struct. First value 0-255 is the DMX value for the channel I am working with. The second value is the brightness for that value, 0-255.
Apologies if you need the whole code, I was trying to keep it simple.
The error I'm getting when I uncomment this line is:-
exit status 1
invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
void sendLedData(uint8_t send_dmx_value, uint8_t send_dmx_brightness)
{
struct led_command send_data;
send_data.value = send_dmx_value;
send_data.brightness = send_dmx_brightness;
// struct led_command send_data;
//send_data.opmode = op_mode;
// send_data.data = data;
for (int i = 0; i < NUMBER_OF_CLIENTS; i++)
{
IPAddress ip(192,168,4,2 + i);
UDP.beginPacket(ip, 7001);
Serial.print("Send DMX Value:");
Serial.print(send_dmx_value);
Serial.print(": Send DMX Brightness:");
Serial.print(send_dmx_brightness);
Serial.println();
// UDP.write((char*)&send_data,sizeof(struct led_command));
UDP.endPacket();
}
}
You failed to include enough code for me to determine exactly which libraries you're using. But, looking in 'Ethernet.h' under the EthernetUDP class, I see:
virtual size_t write(const uint8_t *buffer, size_t size);
So, I'd try casting your struct's address to a 'const uint8_t *' rather than a 'char *'.
gfvalvo:
You failed to include enough code for me to determine exactly which libraries you're using. But, looking in 'Ethernet.h' under the EthernetUDP class, I see:
virtual size_t write(const uint8_t *buffer, size_t size);
So, I'd try casting your struct's address to a 'const uint8_t *' rather than a 'char *'.
Apologies, I was trying to keep the post concise.
I have commented out the old code I have changed, it was previously sending opMode and data.
Here's the full code.
//From https://github.com/luksal/ESP32-DMX-RX
#include <dmx.h>
#include <FastLED.h>
#include <WiFi.h>
#include <WiFiUDP.h>
#include "reactive_common.h"
#define NUMBER_OF_CLIENTS 1
int dmx_start = 10; //DMX starting channel, channel+1 = Brightness
int dmx_value = 0;
int dmx_brightness = 50; //up to 255
int readcycle = 0;
const int checkDelay = 5000;
const int numOpModes = 11;
unsigned long lastChecked;
WiFiUDP UDP;
//struct led_command send_data;
// send_data.value = send_dmx_value;
// send_data.brightness = send_dmx_brightnes;
struct led_command {
uint8_t value;
uint8_t brightness;
};
bool heartbeats[NUMBER_OF_CLIENTS];
static int opMode = 4; //pre-set number to send to slave (for testing)
int old_opMode = 0;
void setup() {
/* WiFi Part */
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.print("------------------------------------------------");
Serial.println();
Serial.print("Setting soft-AP ... ");
WiFi.persistent(false);
WiFi.mode(WIFI_AP);
WiFi.softAP("DMX_WiFi", "123456789");
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
UDP.begin(7171);
resetHeartBeats();
waitForConnections(); //wait here until we have a connection, then resume
lastChecked = millis();
/* DMX part */
Serial.begin(115200);
DMX::Initialize();
}
void loop()
{
if(millis() - readcycle > 1000)
{
readcycle = millis();
Serial.print(readcycle);
if(DMX::IsHealthy())
{
Serial.print(": ok - ");
}
else
{
Serial.print(": fail - ");
}
dmx_value = DMX::Read(dmx_start);
dmx_brightness = DMX::Read(dmx_start+1);
Serial.print("DMX Value:");
Serial.print(dmx_value);
Serial.print(": DMX Brightness:");
Serial.print(dmx_brightness);
Serial.println();
//Serial.print(" - ");
//Serial.print(DMX::Read(dmx_start+2));
//Serial.print(" - ");
//Serial.println(DMX::Read(dmx_start+3));
sendLedData(dmx_value, dmx_brightness);
delay(10);
}
}
void sendLedData(uint8_t send_dmx_value, uint8_t send_dmx_brightness)
{
struct led_command send_data;
send_data.value = send_dmx_value;
send_data.brightness = send_dmx_brightness;
// struct led_command send_data;
//send_data.opmode = op_mode;
// send_data.data = data;
for (int i = 0; i < NUMBER_OF_CLIENTS; i++)
{
IPAddress ip(192,168,4,2 + i);
UDP.beginPacket(ip, 7001);
Serial.print("Send DMX Value:");
Serial.print(send_dmx_value);
Serial.print(": Send DMX Brightness:");
Serial.print(send_dmx_brightness);
Serial.println();
UDP.write((char*)&send_data,sizeof(struct led_command));
UDP.endPacket();
}
}
void waitForConnections() {
while(true) {
readHeartBeat();
if (checkHeartBeats()) {
return;
}
delay(checkDelay);
resetHeartBeats();
}
}
void resetHeartBeats() {
for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
heartbeats[i] = false;
}
}
void readHeartBeat() {
struct heartbeat_message hbm;
while(true) {
int packetSize = UDP.parsePacket();
if (!packetSize) {
break;
}
UDP.read((char *)&hbm, sizeof(struct heartbeat_message));
if (hbm.client_id > NUMBER_OF_CLIENTS) {
Serial.println("Error: invalid client_id received");
continue;
}
heartbeats[hbm.client_id - 1] = true;
}
}
bool checkHeartBeats() {
for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
if (!heartbeats[i]) {
return false;
}
}
resetHeartBeats();
return true;
}
OK, same thing as Ethernet.h. Function prototype from WiFiUDP.h:
virtual size_t write(const uint8_t *buffer, size_t size);
Like I said:
gfvalvo:
So, I'd try casting your struct's address to a 'const uint8_t *' rather than a 'char *'.
BTW, this skeletal (and obviously non-functional) code compiles error-free in Arduino 1.8.12. Target board is an Uno:
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiUDP.h>
struct led_command {
uint8_t value;
uint8_t brightness;
};
WiFiUDP UDP;
led_command send_data;
void setup() {
UDP.write((char*) &send_data, sizeof(send_data));
}
void loop() {
}
gfvalvo:
BTW, this skeletal (and obviously non-functional) code compiles error-free in Arduino 1.8.12. Target board is an Uno:
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiUDP.h>
struct led_command {
uint8_t value;
uint8_t brightness;
};
WiFiUDP UDP;
led_command send_data;
void setup() {
UDP.write((char*) &send_data, sizeof(send_data));
}
void loop() {
}
Thank you for taking the time to put this together.
Weirdly, on my IDE 1.8.12 installation I get a compiler error still with this code.
invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
gfvalvo:
BTW, this skeletal (and obviously non-functional) code compiles error-free in Arduino 1.8.12. Target board is an Uno:
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiUDP.h>
struct led_command {
uint8_t value;
uint8_t brightness;
};
WiFiUDP UDP;
led_command send_data;
void setup() {
UDP.write((char*) &send_data, sizeof(send_data));
}
void loop() {
}
Apologies, I should have been clearer.
Yes, this compiles against a UNO.
However, it still fails for me against a ESP32 Dev Module. I would have hoped for better compatibility.
Can anyone advise?