I try to start a array in the header file
rs485.h
class RS485
{
public:
uint8_t off[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
void sendmsg(uint8_t* cmd);
};
rs485.cpp
void RS485::sendmsg(uint8_t* cmd)
{
//digitalWrite(ENTX_PIN, HIGH); // enable to transmit
Serial.println("sending message------------");
Serial2.write(cmd[0]);
Serial.println(cmd[0], HEX);
Serial2.write(cmd[1]);
Serial.println(cmd[1], HEX);
Serial2.write(cmd[2]);
Serial.println(cmd[2], HEX);
Serial2.write(cmd[3]);
Serial.println(cmd[3], HEX);
Serial2.write(cmd[4]);
Serial.println(cmd[4], HEX);
Serial2.write(cmd[5]);
Serial.println(cmd[5], HEX);
Serial2.write(cmd[6]);
Serial.println(cmd[6], HEX);
Serial2.write(cmd[7]);
Serial.println(cmd[7], HEX);
Serial.println("--------------------------");
}
main.cpp
void callback(char *topic, byte *payload, unsigned int length)
{
'''omit'''
if (cmd)
{
Serial.print("cmd: ");
Serial.println(cmd);
if (cmd == 700)
{
rs485.sendmsg(rs485.off);
}
else if (cmd == 701)
{
rs485.sendmsg(rs485.on);
}
'''omit'''
}
'''omit'''
}
complier have an error message of "too many initializer values".
When I try to use
uint8_t off[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
it build normally. The problem is when in use this variable in main.cpp and pass it to rs485.cpp only one element off[0] is pass normally.
rs485.sendmsg(rs485.off);
I have use serial print to check all value it can all print out but the rs485 cannot tx all char.
Serial2.write(cmd[0]);
Serial.println(cmd[0], HEX);
Serial2.write(cmd[1]);
Serial.println(cmd[1], HEX);
Serial2.write(cmd[2]);
Serial.println(cmd[2], HEX);
Serial2.write(cmd[3]);
Serial.println(cmd[3], HEX);
Serial2.write(cmd[4]);
Serial.println(cmd[4], HEX);
Serial2.write(cmd[5]);
Serial.println(cmd[5], HEX);
Serial2.write(cmd[6]);
Serial.println(cmd[6], HEX);
Serial2.write(cmd[7]);
Serial.println(cmd[7], HEX);
Any result for that?
add the wiring
gpio26 -->DE+RE
gpio21 -->DI
gpio25 -->RO
A member variable declared as
uint8_t off[] = { ... };
does not become an array with the number of elements in the initializer list, like when you declare a non-member variable. Instead, it then becomes a "flexible array" (a C thing that g++ enables by default in C++) - and flexible arrays can't have initializers, which is why you get "too many initializer values".
The correct way is therefore to specify the number of elements:
uint8_t off[8] = { ... };
I suggest that you send them all out at once and check how many that are actully written:
size_t written = Serial2.write(cmd, 8);
Serial.println(written);
This should display 8 if the sending code works.
Related
I can send a request and get an response (modbus RTU frame) from the device (flow meter) but I cannot convert hex to float. Otherwise everything works fine and the way I want it. Does anyone know how to improve it in a simple way?
void loop() {
const char msg_reguest[] = {0x01, 0x04, 0x00, 0x08, 0x00, 0x02, 0xf0, 0x09};
delay(200);
int i;
int len=8;
Serial.println("WYSŁANA RAMKA");
for(i = 0 ; i < len ; i++){
Serial2.write(msg_reguest[i]);
Serial.print("[");
Serial.print(i);
Serial.print("]");
Serial.print("=");
Serial.print("Ox");
Serial.print(String(msg_reguest[i], HEX));
Serial.print(" ");
}
len = 0;
Serial.println();
Serial.println();
int a = 0;
while(Serial2.available())
{
ByteArray[a] = Serial2.read();
a++;
}
int b = 0;
String registros;
Serial.println("ODEBRANA RAMKA");
for(b = 3 ; b < a-2 ; b++){
Serial.print("[");
Serial.print(b);
Serial.print("]");
Serial.print("=");
Serial.print("Ox");
registros =String(ByteArray[b], HEX);
Serial.print(registros);
Serial.print(" ");
}
byte hexArray[] = "registros";
float value;
memcpy(&value, hexArray, sizeof(hexArray));
Serial.println(value);
}
the point is that I have an esp32, TTL rs485 and a flow meter with rs485. I download a frame each time with a different data value. I display the frame with the flow data in the serial monitor in the form of HEX. Esp32 are little Endian, so I want to change the order of numbers and write a function that will automatically convert to float. In the above code I try to do it but it doesn't work
I am trying to read a QR code and send it the phpMyAdmin. I am using a DE2120 1D2D scanner and a UNO. The problem is with the printing , on the serial monitor looks like a string but in the php the each character from the code is printed on a new line, the idea is to client.print the entire code on the same row.
Code bellow:
#include "SparkFun_DE2120_Arduino_Library.h"
#include "SoftwareSerial.h"
#include <Ethernet.h>
#define BUFFER_LEN 40
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE }; //
IPAddress ip(192, 168, 1, 22 ); //
IPAddress gateway(10, 74, 0, 1);
IPAddress subnetMask(255, 255, 255, 192);
EthernetClient cliente;
char server[] = "192.168.1.15"; //
SoftwareSerial softSerial(3,2);
DE2120 scanner;
char scanBuffer[BUFFER_LEN];
String QR;
void setup() {
Serial.begin(115200);
softSerial.begin(9600);
Serial.println(scanner.begin(softSerial));
Ethernet.begin(mac, ip);
IPAddress newSubnet(255, 255, 255, 192);
Ethernet.setSubnetMask(newSubnet);
Serial.print("Ethernet.localIP: ");
Serial.println(Ethernet.localIP());
Serial.print("Ethernet.gatewayIP:");
Serial.println(Ethernet.gatewayIP());
Serial.print("Ethernet.subnetMask:");
Serial.println(Ethernet.subnetMask());
if (cliente.connect(server, 8080)) {
Serial.println("Connected to the server");}
}
void loop() {
delay(200);
if(scanner.readBarcode(scanBuffer, BUFFER_LEN)){
Serial.println("QR availbale ");
for(int i = 0; i < strlen(scanBuffer); i++){ // Production Order
Serial.print(scanBuffer[i]);
QR = String(scanBuffer[i]);
(cliente.connect(server, 8080));
cliente.print("GET /ethernet/data_qr.php?");
cliente.print("QR=");
cliente.println(QR); // I tried also with client.print(QR) followed by client.println(), no chance.
//client.println();
cliente.stop();
}
Serial.println();
}
}
Serial monitor - QR is a String
Client.print result
I tried:
To convert the Char scanBuffer[i] to String and than printed. - 0 results
To store the serial monitor value ov scanBuffer[i] in a variable and the printed. - 0 results
Client.println / Client.print
What can I try , some ideas on order to client.print the QR content in the same row.
Thank you ! :D
I want to use the openssl library in C++ to decrypt data.
I have the key and IV and the encoded base64 string.
I couldn't make it through the documentation, all decryption methods in the header file (openssl/des.h) take 3 keys.
I've managed to achieve the result with the following python code.
from pyDes import *
import base64
key = base64.b64decode("****")
iv = base64.b64decode("***")
enc = base64.b64decode("******")
encryptor = triple_des(key, CBC, iv)
plain = encryptor.decrypt(enc)
print(plain.decode("utf-8"))
I want to get the same result using C++ code and OpenSSL library.
3DES uses three keys. The python function you are using probably derives three keys from the key argument you pass, probably splitting it in three parts.
To use the OpenSSL function, you have to generate 3 keys with 8 bytes each (or a 24 bytes key split in 3).
I adapted the code I found here to use ECB instead of CBC. But, for security reasons, you should consider using CBC, or even AES encryption instead of 3DES.
The example only shows how to use the DES_ecb3_encrypt function with hard coded keys. In a final solution, you have to generate your own keys, using a good RNG.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/des.h>
/* Triple DES key for Encryption and Decryption */
DES_cblock Key1 = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
DES_cblock Key2 = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
DES_cblock Key3 = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33 };
DES_key_schedule SchKey1,SchKey2,SchKey3;
/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len);
int main()
{
/* Input data to encrypt */
DES_cblock input_data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x8};
/* Check for Weak key generation */
if ( -2 == (DES_set_key_checked(&Key1, &SchKey1) || DES_set_key_checked(&Key2, &SchKey2) || DES_set_key_checked(&Key3, &SchKey3)))
{
printf(" Weak key ....\n");
return 1;
}
/* Buffers for Encryption and Decryption */
DES_cblock cipher;
DES_cblock text;
/* Triple-DES ECB Encryption */
DES_ecb3_encrypt(&input_data, &cipher, &SchKey1, &SchKey2, &SchKey3, DES_ENCRYPT);
/* Triple-DES ECB Decryption */
DES_ecb3_encrypt(&cipher, &text, &SchKey1, &SchKey2, &SchKey3, DES_DECRYPT);
/* Printing and Verifying */
print_data("\n Original ", (const void*) input_data, sizeof(input_data));
print_data("\n Encrypted", (const void*) cipher, sizeof(input_data));
print_data("\n Decrypted", (const void*) text, sizeof(input_data));
return 0;
}
void print_data(const char *tittle, const void* data, int len)
{
printf("%s : ",tittle);
const unsigned char * p = (const unsigned char*)data;
int i = 0;
for (; i<len;++i)
printf("%02X ", *p++);
printf("\n");
}
OpenSSL reference:
void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
DES_key_schedule *ks1, DES_key_schedule *ks2,
DES_key_schedule *ks3, int enc);
DES_ecb3_encrypt() encrypts/decrypts the input block by using three-key Triple-DES encryption in ECB mode. This involves encrypting the input with ks1, decrypting with the key schedule ks2, and then encrypting with ks3. This routine greatly reduces the chances of brute force breaking of DES and has the advantage of if ks1, ks2 and ks3 are the same, it is equivalent to just encryption using ECB mode and ks1 as the key.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I make a controller of heating with DS18B20 and Wemos D1 board, but if i try print or check the temperature in if then give back 0 in int.
What is the problem?
// This Arduino sketch reads DS18B20 "1-Wire" digital
// temperature sensors.
// Copyright (c) 2010 Mark McComb, hacktronics LLC
// License: http://www.opensource.org/licenses/mit-license.php (Go crazy)
// Tutorial:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 0
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
const int mintemp = 30;
DeviceAddress insideThermometer = { 0x28, 0xFF, 0x83, 0x51, 0xB2, 0x17, 0x4, 0x8A };
DeviceAddress outsideThermometer = { 0x28, 0xFF, 0x4F, 0xAB, 0xC4, 0x17, 0x5, 0x83 };
DeviceAddress dogHouseThermometer = { 0x28, 0xFF, 0xBF, 0xA9, 0xC4, 0x17, 0x4, 0x7C };
void setup(void)
{
// start serial port
Serial.begin(112500);
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(insideThermometer, 10);
sensors.setResolution(outsideThermometer, 10);
sensors.setResolution(dogHouseThermometer, 10);
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
Serial.print("Error getting temperature");
} else {
Serial.print("C: ");
Serial.print(tempC);
Serial.print(" F: ");
Serial.print(DallasTemperature::toFahrenheit(tempC));
}
}
void loop(void)
{
delay(2000);
Serial.print("Getting temperatures...\n\r");
sensors.requestTemperatures();
Serial.print("Inside temperature is: ");
printTemperature(insideThermometer);
Serial.print("\n\r");
Serial.print("Outside temperature is: ");
printTemperature(outsideThermometer);
Serial.print("\n\r");
Serial.print("Dog House temperature is: ");
printTemperature(dogHouseThermometer);
Serial.print("\n\r\n\r");
int insideThermometer = (int)insideThermometer;
Serial.print(insideThermometer); //In Serial this give 0.
if(insideThermometer > mintemp){
Serial.print("work");
Serial.print(insideThermometer);
}
}
In this line:
int insideThermometer = (int)insideThermometer;
You create a local variable and assign it to itself. Not what you wanted. The global var you are trying to use is
DeviceAddress insideThermometer = { 0x28, 0xFF, 0x83, 0x51, 0xB2, 0x17, 0x4, 0x8A };
If you look at the source code, DeviceAddress is typdef'd as
typedef uint8_t DeviceAddress[8];
If you want to get the temperature you need to call sensors.getTempC(insideThermometer), which you already do in the printTemperature function. Since you call that function before testing the temp, just modify it to return the temp:
float printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
float tempF = 0;
if (tempC == -127.00) {
Serial.print("Error getting temperature");
} else {
Serial.print("C: ");
Serial.print(tempC);
Serial.print(" F: ");
tempF = DallasTemperature::toFahrenheit(tempC);
Serial.print(tempF);
}
return tempF;
}
Then change to
int insideTempF = printTemperature(insideThermometer);
....
if (insideTempF > mintemp) {
....
(You may want to change the name of the function to something like printAndReturnTemperature as that more clearly states its new functionality.)
I'm trying to send some data to a device using serial comunication:
void VcpBridge::write_speed(char address, int spd) {
uint8_t speed = (uint8_t)(127);
ROS_ERROR("VCP BRIDGE: Sending %u to %u", speed, address);
char msg[8];
char command = 0x55, size = 0x02, csum;
csum = speed + 0x64 + address;
sprintf(msg, "%c%c%c%c%c%c", command, address, speed, size, 0x64, csum);
ROS_ERROR(msg);
write(fd_, msg, 6);
}
ROS_ERROR here does the same as printf.
Everything works fine except when the value of speed is over 127. Then it always prints a ? in it's position and the device doesn't recive the right info. Do you know any way to cast it correctly? I've tried %u but then the program crashes.
There is no good reason to use sprintf in your example. Try this:
void VcpBridge::write_speed(char address, int spd) {
uint8_t speed = (uint8_t)(127);
ROS_ERROR("VCP BRIDGE: Sending %u to %u", speed, address);
char command = 0x55, size = 0x02, csum;
csum = speed + 0x64 + address;
ROS_ERROR(msg);
char msg[] = { command, address, speed, size, 0x64, csum};
write(fd_, msg, sizeof msg);
}
Thanks to your answer I could figure out hot to fix the problem. Not using sprintf and using unsigned int was the kay.There's the final code:
void VcpBridge::write_speed(char address,int spd){
uint8_t speed = (uint8_t)(200);
unsigned char command = 0x55, size=0x02, csum;
csum=speed+0x64+address;
unsigned char msg[8]= { command, address, speed, size, 0x64, csum };
write( fd_, msg, 6);
}