Hi, I am developing a project to read Moisture, Salinity and Temperature underground. I'm new to coding and can't seem to get the coding for SigFox transmission right.
I've managed to get all the desired data displayed on the serial monitor and would like this data to be viewed on the SigFox backend. I've been trying for quite some time along with reading other threads for data transmission with no luck.
If anyone could help get me any step closer would be greatly appreciated!
#include <ArduinoLowPower.h>
#include <Wire.h>
#define D6T_ADDR 0x0A
#define D6T_CMD 0x4C // for D6T-44L-06/06H, D6T-8L-09/09H, for D6T-1A-01/02
#define N_ROW 1
#define N_PIXEL 1
#define N_READ ((N_PIXEL + 1) * 2 + 1)
uint8_t rbuf[N_READ];
double ptat;
double pix_data[N_PIXEL];
uint8_t calc_crc(uint8_t data) {
int index;
uint8_t temp;
for (index = 0; index < 8; index++) {
temp = data;
data <<= 1;
if (temp & 0x80) {data ^= 0x07;}
}
return data;
}
bool D6T_checkPEC(uint8_t buf[], int n) {
int i;
uint8_t crc = calc_crc((D6T_ADDR << 1) | 1); // I2C Read address (8bit)
for (i = 0; i < n; i++) {
crc = calc_crc(buf[i] ^ crc);
}
bool ret = crc != buf[n];
if (ret) {
Serial.print("PEC check failed:");
Serial.print(crc, HEX);
Serial.print("(cal) vs ");
Serial.print(buf[n], HEX);
Serial.println("(get)");
}
return ret;
}
/** <!-- conv8us_s16_le {{{1 --> convert a 16bit data from the byte stream.
*/
int16_t conv8us_s16_le(uint8_t* buf, int n) {
uint16_t ret;
ret = (uint16_t)buf[n];
ret += ((uint16_t)buf[n + 1]) << 8;
return (int16_t)ret; // and convert negative.
}
void setup() {
Serial.begin(9600); // Serial baudrate = 9600bps
Wire.begin(); // i2c master
delay(220);
}
void loop() {
int condVal;
const int dry = 764; // value for dry sensor
const int wet = 379; // value for wet sensor
int sensorVal = analogRead(A0);
int sensorVal2 = analogRead(A1);
// Sensor has a range of 379 to 764
// We want to translate this to a scale or 0% to 100%
int percentageHumidity1 = map(sensorVal, wet, dry, 100, 0);
int percentageHumidity2 = map(sensorVal2, wet, dry, 100, 0);
int i = 0;
int16_t itemp = 0;
// Read data via I2C
// I2C buffer of "Arduino MKR" is 256 buffer. (It is enough)
memset(rbuf, 0, N_READ);
Wire.beginTransmission(D6T_ADDR); // I2C slave address
Wire.write(D6T_CMD); // D6T register
Wire.endTransmission();
Wire.requestFrom(D6T_ADDR, N_READ);
while (Wire.available()) {
rbuf[i++] = Wire.read();
}
D6T_checkPEC(rbuf, N_READ - 1);
//Convert to temperature data (degC)
for (i = 0; i < N_PIXEL; i++) {
itemp = conv8us_s16_le(rbuf, 2 + 2*i);
pix_data[i] = (double)itemp / 10.0;
//Outputs
Serial.print("Temperature: ");
for (i = 0; i < N_PIXEL; i++) {
Serial.print(pix_data[i], 1);
}
Serial.println(" [°C]");
}
Serial.print("Sensor 1: ");
Serial.print(percentageHumidity1);
Serial.print("% ");
Serial.print("Sensor 2: ");
Serial.print(percentageHumidity2);
Serial.println("%");
condVal = analogRead(A2);
float Voltage = condVal*(5/1024.0);
Serial.println("Relative Conductance: ");
Serial.println(Voltage);
Serial.println( );
delay(5000);
}
I've tried this and seem to get the error - " 'i' was not declared in this scope". I assume I've just left something out but have wrecked my head trying to figure it out. It seems to be a problem with the 'packed' structure
int16_t pix_data[i], 1
Any ideas where I've gone wrong again, thanks in advance.
#include <ArduinoLowPower.h>
#include <SigFox.h>
#include <Wire.h>
#define D6T_ADDR 0x0A
#define D6T_CMD 0x4C // for D6T-44L-06/06H, D6T-8L-09/09H, for D6T-1A-01/02
#define N_ROW 1
#define N_PIXEL 1
#define N_READ ((N_PIXEL + 1) * 2 + 1)
typedef struct __attribute__ ((packed)) sigfox_message {
uint8_t percentageHumidity1;
uint8_t percentageHumidity2;
int16_t condVal;
int16_t pix_data[i], 1;
} SigfoxMessage;
// stub for message which will be sent
SigfoxMessage msg;
uint8_t rbuf[N_READ];
double ptat;
double pix_data[N_PIXEL];
uint8_t calc_crc(uint8_t data) {
int index;
uint8_t temp;
for (index = 0; index < 8; index++) {
temp = data;
data <<= 1;
if (temp & 0x80) {data ^= 0x07;}
}
return data;
}
bool D6T_checkPEC(uint8_t buf[], int n) {
int i;
uint8_t crc = calc_crc((D6T_ADDR << 1) | 1); // I2C Read address (8bit)
for (i = 0; i < n; i++) {
crc = calc_crc(buf[i] ^ crc);
}
bool ret = crc != buf[n];
if (ret) {
Serial.print("PEC check failed:");
Serial.print(crc, HEX);
Serial.print("(cal) vs ");
Serial.print(buf[n], HEX);
Serial.println("(get)");
}
return ret;
}
/** <!-- conv8us_s16_le {{{1 --> convert a 16bit data from the byte stream.
*/
int16_t conv8us_s16_le(uint8_t* buf, int n) {
uint16_t ret;
ret = (uint16_t)buf[n];
ret += ((uint16_t)buf[n + 1]) << 8;
return (int16_t)ret; // and convert negative.
}
void setup() {
Wire.begin(); // i2c master
delay(220);
if (!SigFox.begin()) {
// Something is really wrong, try rebooting
// Reboot is useful if we are powering the board using an unreliable power source
// (eg. solar panels or other energy harvesting methods)
reboot();
int i = 0;
int16_t itemp = 0;
}
}
//Send module to standby until we need to send a message
SigFox.end();
SigFox.debug();
}
void loop() {
int condVal;
const int dry = 764; // value for dry sensor
const int wet = 379; // value for wet sensor
int sensorVal = analogRead(A0);
int sensorVal2 = analogRead(A1);
int condVal = analogRead(A2);
// Sensor has a range of 379 to 764
// We want to translate this to a scale or 0% to 100%
int percentageHumidity1 = map(sensorVal, wet, dry, 100, 0);
int percentageHumidity2 = map(sensorVal2, wet, dry, 100, 0);
int i = 0;
int16_t itemp = 0;
// Read data via I2C
// I2C buffer of "Arduino MKR" is 256 buffer. (It is enough)
memset(rbuf, 0, N_READ);
Wire.beginTransmission(D6T_ADDR); // I2C slave address
Wire.write(D6T_CMD); // D6T register
Wire.endTransmission();
Wire.requestFrom(D6T_ADDR, N_READ);
while (Wire.available()) {
rbuf[i++] = Wire.read();
}
D6T_checkPEC(rbuf, N_READ - 1);
//Convert to temperature data (degC)
ptat = (double)conv8us_s16_le(rbuf, 0) / 10.0;
for (i = 0; i < N_PIXEL; i++) {
itemp = conv8us_s16_le(rbuf, 2 + 2*i);
pix_data[i] = (double)itemp / 10.0;
// Start the module
SigFox.begin();
// Wait at least 30ms after first configuration (100ms before)
delay(100);
// We can only read the module temperature before SigFox.end()
temperature = SigFox.internalTemperature();
msg.moduleTemperature = convertoFloatToInt16(temperature, 60, -60);
// Clears all pending interrupts
SigFox.status();
delay(1);
SigFox.beginPacket();
SigFox.write((percentageHumidity1)&msg, 12);
SigFox.write((percentageHumidity2)&msg, 12);
SigFox.write((conVal)&msg, 12);
SigFox.write((pix_data[i], 1)&msg, 12);
SigFox.endPacket();
SigFox.end();
//Sleep for 15 minutes
LowPower.sleep(15 * 60 * 1000);
}
void reboot() {
NVIC_SystemReset();
while (1) ;
}