void loop() {
// put your main code here, to run repeatedly:
// send packet
p = (bme.readPressure() / 100.0F );
h = (bme.readHumidity());
t = (bme.readTemperature());
alt = bme.readAltitude(SEALEVELPRESSURE_HPA);
String data = String(h) + "-" + String(t)+ "-" + String(p)+ "-" + String(alt);
int dataLength = data.length(); dataLength++;
uint8_t total[dataLength]; //variable for data to send
data.toCharArray(total, dataLength); //change type data from string ke uint8_t
Serial.println(data);
rf95.send(total, dataLength); //send data
rf95.waitPacketSent();
delay(2000);
}
im using the radiohead library and it works really well on arduino to send the data and then receives on a esp32, but if i make the esp32 the sender with this code
it throws me this error
error: invalid conversion from 'uint8_t*' {aka 'unsigned char*'} to 'char*' [-fpermissive]
refer to toCharArray() function in arduino reference as they stated that :
myString.toCharArray(buf, len)
buf: the buffer to copy the characters into. Allowed data types: array of char.
so the function expects a parameter of type char* not uint8_t*
so either change :
uint8_t total[dataLength]; -> char total[dataLength];
or
data.toCharArray(total, dataLength); -> data.toCharArray((char*)total, dataLength);
either of them should solve your problem.
Related
I am using Arduino UNO and a PN532 NFC module to receive P2P NDEF messages from an Android phone.
I am sending a plaintext string "Hello". When the transfer is successful, I get this on my Arduino:
image
How can I extract the string "Hello" (I think the pairs of numbers before it is the "Hello" in hexadecimal, same for the "text/plain" type indication, type length and payload length) from the NDEF message payload into a regular variable?
Here is my Arduino code:
// Receive a NDEF message from a Peer
// Requires SPI. Tested with Seeed Studio NFC Shield v2
#include "SPI.h"
#include "PN532_SPI.h"
#include "snep.h"
#include "NdefMessage.h"
PN532_SPI pn532spi(SPI, 10);
SNEP nfc(pn532spi);
uint8_t ndefBuf[128];
void setup() {
Serial.begin(9600);
Serial.println("NFC Peer to Peer Example - Receive Message");
}
void loop() {
Serial.println("Waiting for message from Peer");
//string payload = nfc.read();
int msgSize = nfc.read(ndefBuf, sizeof(ndefBuf));
NdefMessage msg = NdefMessage(ndefBuf, msgSize);
msg.print();
}
A NdefMessage is made up of multiple NdefRecord items and you msg has 1 record
so this should do it (not tested)
// Get the first record
NdefRecord record = msg.getRecord(0);
// Get the payload size
byte length = record.getPayloadLength();
// Create byte array big enough for payload
byte payload[length];
// Get payload to byte array
record.getPayload(payload);
// Convert byte Array to string
String string = String((char *)payload);
I get this error with PlatortmIO
src\main.cpp: In function 'void loop()':
src\main.cpp:56:38: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
static char msg = str_out.c_str();
^
*** [.pio\build\esp01\src\main.cpp.o] Error 1
========================== [FAILED] Took 3.48 seconds ==========================/
433 MHz RF Module Transmitter BME280
*/
#include <RH_ASK.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
float hum; // Stores humidity value in percent
float temp; // Stores temperature value in Celcius
float press; // Stores pressor value
// Define output strings
String str_humid;
String str_temp;
String str_press;
String str_out;
// Create Amplitude Shift Keying Object
RH_ASK rf_driver;
void setup()
{
Serial.begin(9600);
Serial.println(F("BME280 test"));
bool status;
// Initialize ASK Object
rf_driver.init();
// Start BME Sensor
status = bme.begin(0x76);
if (!status)
{
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void loop()
{
delay(2000); // Delay so sensor can stabalize
hum = bme.readHumidity(); // Get Humidity value
temp= bme.readTemperature(); // Get Temperature value
press= bme.readPressure(); //Get Pressoure
// Convert Humidity to string
str_humid = String(hum);
// Convert Temperature to string
str_temp = String(temp);
//Convert Pressessor
str_press = String (press);
// Combine Humidity and Temperature
str_out = str_humid + "," + str_temp + "," + str_press;
// Compose output character
static char *msg = str_out.c_str();
rf_driver.send((uint8_t *)msg, strlen(msg));
rf_driver.waitPacketSent();
}
String.c_str() return a const char* array, which is not compatible with your static char* msg.
Looking at your code, instead of converting float to String in order to use String concatenation, then convert to an array, it will be much simpler to just directly create a char array with sprintf().
hum = bme.readHumidity(); // Get Humidity value
temp= bme.readTemperature(); // Get Temperature value
press= bme.readPressure(); //Get Pressoure
char msg[50];
sprintf(msg, "%f,%f,%f", hum, temp, press);
String concatenation isn't safe in Arduino which has only 2k memory and should avoid whenever is possible, especially if you are new to Arduino programming and not familiar with how dynamic memory allocation works internally.
I am publishing sensor readings to thingSpeak using its mqttAPI. I have deployed my project on Huzzah esp8266 board. After just publishing one value, I'm getting ESP exception 9, 28. I guess I'm having problem with loop() function. Here's my code
void loop() {
if(!mqttCli.connected()){
reconnectMQTT();
}
mqttCli.loop();
if(millis()-mqttTimer>mqttInterval){
taskWiFiCallback();
}
}
void taskWiFiCallback(){
Serial.println("task WiFi Started");
if(!mqttCli.connected()){
Serial.println("mqtt not connected");
reconnectMQTT();
return;
}
Serial.println("mqtt Connection established");
Serial.println("State:" + mqttCli.connected());
String topicString ="channels/"+String(channelID)+"/publish/"+String(writeAPIKey);
int topicLength = topicString.length();
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength+1);
Serial.println(topicBuffer);
String dataString = String("field1="+ String(tempC,1) + "&field2=" + String(tempF,1) + "&field3=" + String(humid,1));
int dataLength = dataString.length();
char dataBuffer[dataLength];
dataString.toCharArray(dataBuffer,dataLength+1);
Serial.println(dataBuffer);
Serial.println(mqttCli.publish(topicBuffer,dataBuffer) ? "Published" : "Not Published Bawa, Do Something");
mqttTimer = millis();
}
void reconnectMQTT(){
Serial.println("setting up mqtt");
WiFiClient wifiClient;
mqttCli.setServer(mqtt_server,1883);
mqttCli.setClient(wifiClient);
mqttCli.setCallback(&callback);
// Creating a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
while(!mqttCli.connected()){
if(mqttCli.connect(clientId.c_str())){
String subTopic = String("channels/"+ String(channelID) +
"/subscribe/json/" + String(readAPIKey));
int subTopicLength = subTopic.length();
char subTopicBuffer[subTopicLength];
subTopic.toCharArray(subTopicBuffer,subTopicLength);
String pubTopic ="channels/" + String( channelID ) +
"/publish/"+String(writeAPIKey);
char pubTopicBuffer[pubTopic.length()];
pubTopic.toCharArray(pubTopicBuffer,pubTopic.length()+1);
String message = String("field1=" + String(tempC,1) + "&field2=" +
String(tempF,1) + "&field3=" + String(humid,1));
char messageBuffer[message.length()];
message.toCharArray(messageBuffer,message.length()+ 1);
Serial.println(messageBuffer);
Serial.println(mqttCli.publish(pubTopicBuffer,messageBuffer) ? "Published" : "Unpublished");
Serial.println(mqttCli.subscribe(subTopicBuffer) ? "Subscribed" : "Unsubscribed");
}else{
Serial.print("failed, rc=");
Serial.println(mqttCli.state());
delay(1000);
}
}
}
I have Subscribed to the topic and it is giving correct results and even publish in reconnectMQTT() function is being published.
There may be other problems, but to start:
int topicLength = topicString.length();
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength+1);
You're declaring a buffer of topicLength bytes and then copying topicLength + 1 bytes into it. You'll always overrun the buffer by one byte. You need to declare it to be topicLength + 1 bytes long in order to have room for the C language \0 string terminator. So:
int topicLength = topicString.length();
char topicBuffer[topicLength+1];
topicString.toCharArray(topicBuffer,topicLength+1);
or, better:
int topicLength = topicString.length()+1;
char topicBuffer[topicLength];
topicString.toCharArray(topicBuffer,topicLength);
Same thing for dataBuffer later as well as pubTopic, messageBuffer and any other place that you turn a String into a char array.
Also, note that your line
subTopic.toCharArray(subTopicBuffer,subTopicLength);
doesn't add 1 to the length where you do add 1 to the length everywhere else.
I'm using ArduinoJSON to write a couple of data points to my EEPROM on Arduino Uno. I'm running into a problem with getGroundedPR where I need to convert a uint8_t to a char to pass retrieved data into my JSON parser.
This is my first time using EEPROM so I'm willing to bet there's a better way to do this. Should I continue to use JSON or is there a better way? I'm being cautious of the 10k write limit (give or take) on the EEPROM.
the EEPROM read/write is commented out until I have my process nailed down
void IMUController::setGroundedPR(double p, double r) {
Serial.print("Setting IMU ground: ");
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["pitch"] = p;
root["roll"] = r;
root.printTo(Serial);
char buffer[256];
root.printTo(buffer, sizeof(buffer));
Serial.println();
// EEPROM.write(EEPROM_ADDRESS_IMU_GROUNDED, buffer);
}
double* IMUController::getGroundedPR() {
double ret[2] = {0, 0};
StaticJsonBuffer<200> jsonBuffer;
uint8_t json_saved = EEPROM.read(EEPROM_ADDRESS_IMU_GROUNDED);
char json[] = "asdf"; // convert json_saved to char here
JsonObject& root = jsonBuffer.parseObject(json);
if(!root.success()) {
// return the result
ret[0] = (double)root["pitch"];
ret[1] = (double)root["roll"];
return ret;
}
return ret;
}
The EEPROM functions read() and write() only deal with a single character. You need to use put() and get() to deal with arrays.
char buffer[256];
root.printTo(buffer, sizeof(buffer));
EEPROM.put(EEPROM_ADDRESS_IMU_GROUNDED, buffer);
And to read it back:
char json[256];
EEPROM.get(EEPROM_ADDRESS_IMU_GROUNDED, json);
JsonObject& root = jsonBuffer.parseObject(json);
You need to take care with he array sizes though, the EEPROM functions will get and put the number of bytes in the array (256). The string should be null terminated so the extra bytes shouldn't cause a problem.
I've written the java code to send data to pic via serial port and now I need to program the microcontroller to read the data and make PortD.RD6=1 if the it receives 1 and PortD.RD6=0 if it receives 0. I've tried this code but I get many errors .
This is my first mikroC program so I really don't know how to manage these errors.
char output[1];
unsigned short i;
void main(){
TRISD = 0x01;
i = 0;
UART1_Init(9600);
while (1) {
if (UART1_Data_Ready()==1) {
i = UART1_Read(); // read the received data
ByteToStr(i, output);
if (output = "1" ) // this is where I get the error
{PortD.RD6=1;}
else { PortD.RD6=0;}
}}}
One error that I can spot is that ByteToStr returns three characters so it is probably overwriting other memory areas and giving an undefined result. You don't need to do that conversion you can simply read a byte into a char and do a comparison directly on that as follows:
void main()
{
char c;
TRISD = 0x01;
UART1_Init(9600);
while (1) {
if (UART1_Data_Ready()) {
c = UART1_Read();
if (c == '1')
PortD.RD6=1;
else
PortD.RD6=0;
}
}
}