I am trying to send the byte array of an image file to the Arduino with the pyserial library. And I am receiving the data byte by byte in the Arduino. But it seems I am unable to retrieve the bytes on the Arduino. For example it sends a string of '255' Arduino receives the byte as '2'.
Python code:
import serial
ser = serial.Serial('/dev/ttyUSB0', 115200, bytesize=8, timeout=0, parity=serial.PARITY_EVEN, rtscts=1)
f = open('image.jpg','rb')
l = f.read()
b = bytearray(l)
for i in range(1,len(b)):
ser.write(str(b[i-1]))
ser.flush()
ser.close()
Arduino code:
char buffer ; // for incoming serial data
int length = 1;
void setup() {
Serial.begin(115200); // opens serial port, sets data rate to 9600 bps
}
void loop() {
Serial.readBytes(&buffer, length) ;
Serial.println(buffer);
}
Your Python code sends numbers as ASCII strings, instead of sending bytes (which is what your Arduino code is expecting...). Instead, do:
for i in range(1,len(b)):
ser.write(b[i-1])
Related
When I upload the code to try 2-way communication of LoRa Sx1278 with Arduino UNO it fails to work. I am using 2 modules with the same code. This is the output I receive:
23:09:27.186 -> Received packet: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^' with RSSI -70
23:09:28.207 -> Sending message
I understand the module receives a message but fails to read it, and the second LoRa module with the receiver code fails.
Here is my code:
#include <Wire.h>
#include <SPI.h>
#include <LoRa.h>
String outgoing;
byte msgCount = 0; // count of outgoing messages
byte localAddress = 0xBB; // address of this device
byte destination = 0xFF; // destination to send to
long lastSendTime = 0; // last send time
int interval = 300; // interval between sends
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("LoRa Two-Way Communication");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
delay(100);
while (1);
}
}
void loop() {
if (millis() - lastSendTime > interval) {
String message = "data from sensors";
Serial.println("Sending message");
sendMessage(message);
// Serial.println("Sending " + message);
lastSendTime = millis(); // timestamp the message
interval = random(50) + 300; // 2-3 seconds
}
// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
}
void sendMessage(String outgoing) {
LoRa.beginPacket(); // start packet
LoRa.write(destination); // add destination address
LoRa.write(localAddress); // add sender address
LoRa.write(msgCount); // add message ID
LoRa.write(outgoing.length()); // add payload length
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
void onReceive(int packetSize) {
if (packetSize == 0) return;
// read packet header bytes:
int recipient = LoRa.read(); // recipient address
byte sender = LoRa.read(); // sender address
byte incomingMsgId = LoRa.read(); // incoming msg ID
byte incomingLength = LoRa.read(); // incoming msg length
// received a packet
Serial.print("Received packet: ");
String LoRaData = LoRa.readString();
Serial.print(LoRaData);
// read packet
while (LoRa.available()) {
Serial.print((char)LoRa.read());
}
// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
delay(1000);
}
I got the code from a tutorial and changed it so it is used to test the module for 2-way communication. Earlier, I tried an example from the library "LoRa Sender" and "LoRa Receiver" and it works flawlessly, so this isn't a hardware issue as far as I am concerned.
There are a few things that are not quite right in the code, but the main one is this: interval = random(50) + 300; // 2-3 seconds That's nowhere near 2 seconds. interval is in milliseconds, so a maximum of 50+300 will give you 0.35 seconds. Which means that both devices are transmitting NON-STOP, and can't hear each other. Try something like 2000 + random(1000)... Although there are better ways to get a random than using random. But anyway.
Also, stay off 433e6, it's a busy frequency, and if there are people nearby with a car remote control, you'll receive a lot of stuff not from you.
I am writing a program to encrypt the given input and send the cipher text over LoRa waves, but I seem to be stuck in this step.
I am using a Heltec LoRa ESP32 and have included the mbedtls library for the AES functions.
#include "mbedtls/aes.h"
#include "heltec.h"
#include <SPI.h>
#define BAND 433E6 //setting the LoRa bands to 433 mhz
mbedtls_aes_context aes;
int counter = 0;
unsigned char key[32] = "key"; // 256 bit - AES = 32 bytes for key
unsigned char iv[16];
unsigned char input [128] = "given AES plain text";
unsigned char output[128];
size_t input_len = 40;
size_t output_len = 0;
void setup() {
Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
//setup code to enable LoRa
Serial.begin(115200); //establishing serial communication with esp32 and pc
mbedtls_aes_setkey_enc( &aes, key, 256 );
mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, 48, iv, input, output ); // AES function from mbedtls library,
}
void loop() {
Serial.print("Sending packet: ");
Serial.println(counter);
Serial.println((char*)output); //here is the issue
// send packet
LoRa.beginPacket();
LoRa.print((char*)output);
LoRa.print(counter);
LoRa.endPacket();
counter++;
delay(5000);
}
the output gives a cipher text containing (Im assuming) special characters and when I look at the Arduino serial monitor it shows bunch of reverse question marks and boxes with normal characters.
Serial.println((char*)output);
Is there a print method that can show these special characters in the Arduino IDE?
I am trying to learn some things about arduino serial reading from a bluetooth device. This is the code I found everywhere:
int incomingByte = 0; // for incoming serial data
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte);
}
}
When I send the word "word" from my mobile bluetooth I get 4 lines:
I received: w
I received: o
I received: r
I received: d
which is fine... But here 's my question:
I want to check the received characters as soon as they come into the serial input, so if one of them is the character "r", I would like an extra line to be printed in the Serial Monitor, something like: "wow, that was an r!"
So I add an if statement after the println(incomingByte) and my code is now like that:
Serial.print("I received: ");
Serial.println(incomingByte);
if (incomingByte == "r") {
Serial.println("wow, that was an r!");
}
That code never works, it 's like not having an "r" at all.
Could someone explain to me?
Thanks
I think it is due to the usage of "r" instead of 'r'. The difference is that in first case you have string, which is char[], and in the second you have single char.
In a sketch of Arduino there is an example WiFi Telnet To Serial with ESP8266. There is a piece of code that is used to receive data from a client:
//check clients for data
for(i = 0; i < MAX_SRV_CLIENTS; i++){
if (serverClients[i] && serverClients[i].connected()){
if(serverClients[i].available()){
//get data from the telnet client and push it to the UART
while(serverClients[i].available())
Serial.write(serverClients[i].read());
}
}
}
This data is sent to the console or the serial port, but I need to capture that data and store it in a byte array:
byte bufferMSGfromCliente[1024]
How to do it?
Its not c++ but you might be able to use a processing sketch. The syntax is very close to arduino so it should be familiar.
import processing.serial.*;
Serial myPort; // The serial port
void setup() {
// List all the available serial ports
printArray(Serial.list());
// Open the port you are using at the rate you want:
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw() {
int i = 0;
byte[] bufferMSGfromCliente = new byte[1024];
while (myPort.available() > 0) {
int inByte = myPort.read();
if(i > 1024)
{
i = 0;
}
bufferMSGfromCliente[i] = inByte;
i++;
}
}
Did you try to write it to another Serial port? Here you write it on the same Serial port as your Serial Monitor.
Best would be to store serverClients[i].read() into a Byte and then Serial.println(Byte) to see what the information is.
After that, ask yourself:
1. What Serial port will this information be sent to, what is the destination?
2. How can I confirm that information is sent succesfully and has the ability to be debugged.
Also, use Serial.flush() to make sure the Serial.write function completes. Eventhough it says ''flush'', the function in Arduino IDE waits for the Serial write function to be completed.
I am trying to get an arduino board to read the state of a potentiometer which is connected to a master arduino board, without connecting the potentiometer to the second board with physical cables
I have tried using Wire.write and Wire.read to just transfer the one value.
The master arduino code:
#include <Wire.h>
const int dial = A0;
int reading = 0;
void setup() {
pinMode(dial, INPUT);
Wire.begin();
}
void loop() {
reading = analogRead(dial);
Wire.beginTransmission(9);
Wire.write(reading);
Wire.endTransmission();
}
The slave arduino code:
#include <Wire.h>
int reading = 0;
void setup() {
Wire.begin(9);
Serial.begin(9600);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int bytes) {
reading = Wire.read();
}
void loop() {
Serial.println(reading);
}
When I read the Serial Monitor, the potentiometer or "reading" in the slave arduino limits at 255 (I don't know why) in 6 intervals (goes from 0 to 255, then drops to 0 and does that 6 times). I expect it to do the full range of the potentiometer to cap out at 1023.
Your ADC is 10bit and won’t fit in a byte. (Wire.write(value) sends value as a single byte). You need to send reading in 2 bytes. Here is how to make 2 bytes.
byte data1 = highByte(reading);
byte data2 = lowByte(reading);
On receiving side, reconstruct an int this way.
byte data1 = Wire.read();
byte data2 = Wire.read();
reading = int(data1) << 8 | data2;