communicating state of a potentiometer with a second arduino board - c++

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;

Related

Arduino UNO LoRa SX1278 not sending/receiving data correctly

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.

Arduino serial monitor gives question marks and boxes with my output

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?

Separating a MQ4 gas Sensor particle photon code into a .h and .cpp files

I am new here. I was working with particle Photon and MQ4 I2C gas sensor.
I have a normal I2C code for this sensor
#include <application.h>
#include <spark_wiring_i2c.h>
// ADC121C_MQ4 I2C address is 0x50(80)
#define Addr 0x50
int raw_adc = 0;
double ppm = 0.0;
void setup()
{
// Set variable
Particle.variable("i2cdevice", "ADC121C_MQ4");
Particle.variable("PPM", ppm);
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise serial communication, set baud rate = 9600
Serial.begin(9600);
delay(300);
}
void loop()
{
unsigned int data[2];
// Start I2C transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write(0x00);
// Stop I2C transmission
Wire.endTransmission();
// Request 2 bytes of data
Wire.requestFrom(Addr, 2);
// Read 2 bytes of data
// raw_adc msb, raw_adc lsb
if (Wire.available() == 2)
{
data[0] = Wire.read();
data[1] = Wire.read();
}
delay(300);
// Convert the data to 12-bits
raw_adc = ((data[0] & 0x0F) * 256) + data[1];
ppm = (10000 / 4096.0) * raw_adc + 200.0;
// Output data to dashboard
Particle.publish("Methane concentration : ", String(ppm));
delay(1000);
}
So I am a noob in coding and don't know how to separate this code into .cpp and .h files to get the clean code.
Please help me out, how this code can be converted into .cpp and .h files.
Thanx in advance.

Transmitting data from GPS to SIGFOX

I'm working on an Arduino board (microprocessor: ATMega328P) for a University project. I'd like to build a GPS tracker which receives data, stores it, and retransmit it via SIGFOX module.
Basically, I'm able to receive data, and I'm able to send simple SIGFOX commands via serial.
#include <TinyGPS++.h>
#include <String.h>
#include <SoftwareSerial.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
Serial.println(F("DeviceExample.ino"));
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println();
}
void loop()
{
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() > 0)
if (gps.encode(ss.read())) {
Serial.print(gps.location.lat(), 6); // 4 bytes
Serial.print(F(",")); // 1 byte
Serial.print(gps.location.lng(), 6); // 4 bytes
Serial.print('\n');
delay(4000);
}
if (millis() > 5000 && gps.charsProcessed() < 10){
Serial.println(F("No GPS detected: check wiring."));
while (true);
}
}
This prints correctly on screen the two values (latitude and longitude) that I need to store.
This is the part of the code in TinyGPS++.cpp :
double TinyGPSLocation::lat()
{
updated = false;
double ret = rawLatData.deg + rawLatData.billionths / 1000000000.0;
return rawLatData.negative ? -ret : ret;
}
double TinyGPSLocation::lng()
{
updated = false;
double ret = rawLngData.deg + rawLngData.billionths / 1000000000.0;
return rawLngData.negative ? -ret : ret;
}
Now I'd like to store this data and send it through the SIGFOX module.
A SIGFOX command is:
'N X'
Where N represents the number of bytes that are to be transmitted, and X are the values of the bytes. For example: '1 255' is 1 byte with value 255, and returns FF as output.
The problem is that the values are doubles so I don't know how to write them in the SIGFOX command.
Another problem is that I don't know how to create two serial communications in the code. I tried it but it doesn't seem to work.
Thank you so much in advance.
I saw some of the API info on the SIGFOX, I'm assuming it is this. Even if it isn't it's probably close enough for the point I'm trying to make.
https://support.sigfox.com/apidocs#operation/getDevice
You need to understand to some extent what IEEE 754 is as in my experience this is how equipment passes the data back and forth if you look at the raw bit stream.
https://en.wikipedia.org/wiki/IEEE_754
So, it is a double you send over 8 bytes on most platforms and 4 bytes for a float. When you print to the screen of hover over a variable in debug mode, the IDE/compiler takes care of this for you and gives you number with decimal points.
For making another serial port, you need to make another variable and pass in the baud rate etc of that device.

Serial communication not working when class is instantiated in Arduino Environment

I'm trying to write code for my Arduino Mega to communicate with ADXL345 accelerometer using c++ style library.
This is my Accelerometer.h file:
#include <Wire.h>
#define ADXL345 (0x53) // I2C Address of ADXL345 accelerometer
struct Acceleration
{
float x;
float y;
float z;
};
class Accelerometer
{
public:
Accelerometer(void); // Constructor
Acceleration readData(void); // Read sensor data
private:
char buffer[6]; // Buffer to store data (x, y, z: LSB and MSB of each)
char DATA_FORMAT; // Address of DATA_FORMAT Register
char POWER_CTL; // Address of POWER_CTL Register
char DATAX0; // Address of X-Axis LSB Data
char DATAX1; // Address of X-Axis MSB Data
char DATAY0; // Address of Y-Axis LSB Data
char DATAY1; // Address of Y-Axis MSB Data
char DATAZ0; // Address of Z-Axis LSB Data
char DATAZ1; // Address of Z-Axis MSB Data
void writeToAccelerometer(char address, char value);
void readFromAccelerometer(char address, int numOfBytes);
};
And this is my Accelerometer.cpp file:
#include "Accelerometer.h"
#include <Wire.h>
Accelerometer::Accelerometer()
{
Wire.begin(); // Initialize I2C bus
writeToAccelerometer(DATA_FORMAT, 0x01); // +/- 4g range
writeToAccelerometer(POWER_CTL, 0x08); // Measurement Mode
DATA_FORMAT = 0x31; // Address of DATA_FORMAT Register
POWER_CTL = 0x2D; // Address of POWER_CTL Register
DATAX0 = 0x32; // Address of X-Axis LSB Data
DATAX1 = 0x33; // Address of X-Axis MSB Data
DATAY0 = 0x34; // Address of Y-Axis LSB Data
DATAY1 = 0x35; // Address of Y-Axis MSB Data
DATAZ0 = 0x36; // Address of Z-Axis LSB Data
DATAZ1 = 0x37; // Address of Z-Axis MSB Data
}
void Accelerometer::writeToAccelerometer(char address, char value)
{
Wire.beginTransmission(ADXL345); // start transmission to ADXL345
Wire.write(address); // send register address
Wire.write(value); // send value to write
Wire.endTransmission(); // end transmission
}
void Accelerometer::readFromAccelerometer(char address, int numOfBytes)
{
Wire.beginTransmission(ADXL345); // start transmission to ADXL345
Wire.write(address); // send register address
Wire.endTransmission(); // end transmission
Wire.beginTransmission(ADXL345); // start transmission to ADXL345
Wire.requestFrom(ADXL345, numOfBytes); // request some bytes from device
int i = 0;
while(Wire.available()) // while there is data
{
buffer[i] = Wire.read(); // receive a byte and save it in the buffer
i++;
}
Wire.endTransmission(); // end transmission
}
Acceleration Accelerometer::readData()
{
Acceleration R;
readFromAccelerometer(DATAX0, 6); // Read data from sensor
// Merge of data and conversion to int format
int x_acceleration = (((int)buffer[1]) << 8) | buffer[0];
int y_acceleration = (((int)buffer[3]) << 8) | buffer[2];
int z_acceleration = (((int)buffer[5]) << 8) | buffer[4];
R.x = x_acceleration*0.0078;
R.y = x_acceleration*0.0078;
R.z = x_acceleration*0.0078;
return R;
}
I'm using this library im my Arduino sketch with this code:
#include <Wire.h>
#include "Accelerometer.h"
Accelerometer accel;
Acceleration Racc;
void setup()
{
Serial.begin(9600); // Start serial for outbut at 9600 bps
}
void loop()
{
Racc = accel.readData();
// Print data
Serial.print("ACCELERATION - X: ");
Serial.print( Racc.x );
Serial.print(" G / Y: ");
Serial.print( Racc.y );
Serial.print(" G / Z: ");
Serial.print( Racc.z );
Serial.print(" G\n");
delay(100);
}
This code is compilated without erros. However, because of the instantiation of Accelerometer class, Serial communication is not working (I can't see any text in Serial Monitor). When I remove the class instance of the code (letting just Serial communication in code), I can see what is print in Serial Monitor.
Does anybody have any idea about what is going on? I would appreciate any help.
As the ADXL345 can operate either SPI or I2C it needs to be configured, as such. In your case of trying to use it as I2C, the CS of the ADXL345 need to be tied to 3.3V
I2C mode is enabled if the CS pinis tied high to VDD I/O. The CS pin
should always be tied high to VDD I/O or be driven by an external
controller because there is nodefault mode if the CS pin is left
unconnected. Therefore, not taking these precautions may result in an
inability to ommunicatewith the part.
Where in your above code I do not see any pins configured as output to drive the CS.
It has been my experience that when the I2C (wire.h) library is not properly connected to a device it can be blocking. Which is similar to your described symptom here.
You may want to reference your code against others, such as https://github.com/jenschr/Arduino-libraries/tree/master/ADXL345. which appears to fully support the many features of the ADXL345 over I2C