I have a very simple question, I suppose... I am programming on a SAMD21 board with two SPI communications (one classis SPI and second int SPI), In my opinion the int SPI does not work correctly. If i connect some senzor, it does print nothing to the serial monitor. I am quite sure, that my code is OK, but perhaps there can be some mistake...
So I need to know, if there is some way to test SPI winhout connecting external devices to the board. Please, do not hate that the code is too long, the code for SPI sensor I am using is marked with "//SPI".
PS: Sorry I deleted the SMUART and MICS6814 measuring and calibrating functions, to use only 30 000 characters. Full code is here: https://mega.nz/file/2QxG0ayZ#4UpEU17ogXnm2NK22zAowlDDRrXzksPzzs05zbuq23o
#include <Adafruit_BME280.h> // include Adafruit BME280 library
#include <Adafruit_INA219.h> // include INA219
#include <SD.h> // include Arduino SD library
#include "Open_Cansat_GPS.h"
#include <RTCZero.h>
//include our new sensors
#include <MICS6814.h>
#include <MICS-VZ-89TE.h>
#include "MQ131.h"
#include <Wire.h>
#include <SPI.h>
#include "RFM69.h" // include RFM69 library
// Local
#define PC_BAUDRATE 115200
#define MS_DELAY 0 // Number of milliseconds between data sending and LED signalization
#define LED_DELAY 100
#define Serial SerialUSB
RTCZero rtc;
// RFM69
#define NETWORKID 0 // Must be the same for all nodes (0 to 255)
#define MYNODEID 1 // My node ID (0 to 255)
#define TONODEID 2 // Destination node ID (0 to 254, 255 = broadcast)
#define FREQUENCY RF69_433MHZ // Frequency set up
#define FREQUENCYSPECIFIC 433000000 // Should be value in Hz, now 433 Mhz will be set
#define CHIP_SELECT_PIN 43 //radio chip select
#define INTERUP_PIN 9 //radio interrupt
// BME280 SETTING
#define BME280_ADDRESS_OPEN_CANSAT 0x77
#define SEALEVELPRESSURE_HPA 1013.25
//define our sensor pins
//MICS6814
#define PIN_CO 0
#define PIN_NO2 0
#define PIN_NH3 0
#define MICS6814Pin 6
//OZONE2CLICK
const byte pinSS = 2;
const byte pinRDY = 12;
const byte pinSCK = 13;
const byte O2Pin = 10;
//SMUART
bool flag1 = false;
bool flag2 = false;
byte rxData[30];
byte one, two;
#define DcPin 8
//MICSVZ89TE
#define MICSVZ89TEPin 7
int datas [7];
bool MICS_status;
int MICS_voc;
int MICS_eqco2;
//PHASES
float CurrentTime;
const byte day = 17;
const byte month = 11;
const byte year = 15;
MICS6814 gas(PIN_CO, PIN_NO2, PIN_NH3);
long accelX, accelY, accelZ;
float gForceX, gForceY, gForceZ;
long gyroX, gyroY, gyroZ;
float rotX, rotY, rotZ;
#define sd_cs_pin 35 // set SD's chip select pin (according to the circuit)
RFM69 radio(CHIP_SELECT_PIN, INTERUP_PIN, true);
typedef struct
{
int16_t messageId;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t sec;
float longitude;
float latitude;
uint8_t num_of_satelites;
float temperature;
float pressure;
float altitude;
float humidity_bme280;
float voltage_shunt;
float voltage_bus;
float current_mA;
float voltage_load;
int16_t rssi;
} messageOut;
messageOut cansatdata; //create the struct variable
Adafruit_BME280 bme;
Adafruit_INA219 ina219(0x40);
OpenCansatGPS gps;
File file; // SD library variable
// LEDS
#define D13_led_pin 42 // D13 LED
#define M_led_pin 36 // MLED
// Local variables
int idCounter = 1;
bool isBmeOk = true;
bool isSdOk = true;
bool isRadioOk = true;
bool isGpsConnected = true;
// My variables
float NH3Data;
float COData;
float NO2Data;
float PPMO2;
float PPBO2;
float MGM3O2;
float UGM3O2;
float SSmoke1;
float SSmoke2;
float SSmoke3;
float ESmoke1;
float ESmoke2;
float ESmoke3;
int DataCounter = 0;
void RTCBegin ()
{
rtc.begin();
}
void RTCSleep ()
{
digitalWrite(O2Pin, LOW);
digitalWrite(MICS6814Pin, LOW);
digitalWrite(MICSVZ89TEPin, LOW);
digitalWrite(DcPin, LOW);
digitalWrite(D13_led_pin, LOW);
digitalWrite(M_led_pin, LOW);
GyroscopeSleep();
byte seconds = 0;
byte minutes = 00;
byte hours = 00;
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmTime(00, 00, 10);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
rtc.standbyMode();
TerrestrialPhase();
// Sleep until next alarm match
}
//SPI
void OZONE2CLICKCalibrate ()
{
Serial.println("2");
//MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000); //(int _pinCS, int _pinRDY, int _pinPower, MQ131Model _model, int _RL)
Serial.println("99");
Serial.println("Calibration in progress...");
MQ131.calibrate();
Serial.println("Calibration done!");
Serial.print("R0 = ");
Serial.print(MQ131.getR0());
Serial.println(" Ohms");
Serial.print("Time to heat = ");
Serial.print(MQ131.getTimeToRead());
Serial.println(" s");
}
void OZONE2CLICKMeasure ()
{
Serial.println("Sampling...");
MQ131.sample();
Serial.print("Concentration O3 : ");
PPMO2 = MQ131.getO3(PPM);
Serial.print(PPMO2);
Serial.println(" ppm");
Serial.print("Concentration O3 : ");
PPBO2 = MQ131.getO3(PPB);
Serial.print(PPBO2);
Serial.println(" ppb");
Serial.print("Concentration O3 : ");
MGM3O2 = MQ131.getO3(MG_M3);
Serial.print(MGM3O2);
Serial.println(" mg/m3");
Serial.print("Concentration O3 : ");
UGM3O2 = MQ131.getO3(UG_M3);
Serial.print(UGM3O2);
Serial.println(" ug/m3");
}
//SPI
void MICSVZ89TEMeasure()
{
delay(5000);
MICS_VZ_89TE myMICS;
MICS_status = myMICS.begin();
myMICS.readSensor();
MICS_eqco2 = myMICS.getCO2();
MICS_voc = myMICS.getVOC();
Serial.print("MICS VOC PPB: ");
Serial.println(MICS_voc);
Serial.print("MICS CO2 PPM: ");
Serial.println(MICS_eqco2);
delay(1000);
}
void GyroscopeTurnOn()
{
Wire.begin();
setupMPU();
}
void GyroscopeMeasure() {
recordAccelRegisters();
recordGyroRegisters();
printData();
}
void setupMPU(){
Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2)
Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
Wire.endTransmission();
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4)
Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s
Wire.endTransmission();
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5)
Wire.write(0b00000000); //Setting the accel to +/- 2g
Wire.endTransmission();
}
void GyroscopeSleep(){
Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2)
Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
Wire.write(0b01000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
Wire.endTransmission();
}
void recordAccelRegisters() {
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x3B); //Starting register for Accel Readings
Wire.endTransmission();
Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40)
while(Wire.available() < 6);
accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
processAccelData();
}
void processAccelData(){
gForceX = accelX / 16384.0;
gForceY = accelY / 16384.0;
gForceZ = accelZ / 16384.0;
}
void recordGyroRegisters() {
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x43); //Starting register for Gyro Readings
Wire.endTransmission();
Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 - 48)
while(Wire.available() < 6);
gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
processGyroData();
}
void processGyroData() {
rotX = gyroX / 131.0;
rotY = gyroY / 131.0;
rotZ = gyroZ / 131.0;
}
void printData() {
Serial.print("Gyro (deg)");
Serial.print(" X=");
Serial.print(rotX);
Serial.print(" Y=");
Serial.print(rotY);
Serial.print(" Z=");
Serial.print(rotZ);
Serial.print(" Accel (g)");
Serial.print(" X=");
Serial.print(gForceX);
Serial.print(" Y=");
Serial.print(gForceY);
Serial.print(" Z=");
Serial.println(gForceZ);
}
void TerrestrialPhase()
{
Serial.println("------------------------------");
Serial.println("TERRESTRIAL PHASE IN PROGRESS");
Serial.println("------------------------------");
Serial.println(" ");
digitalWrite(DcPin, HIGH);
digitalWrite(MICS6814Pin, HIGH);
digitalWrite(MICSVZ89TEPin, HIGH);
digitalWrite(O2Pin, HIGH);
delay(2000);
MICSVZ89TEMeasure();
MICSVZ89TEMeasure();
MICSVZ89TEMeasure();
MICSVZ89TEMeasure();
MICS6814Calibrate();
MICS6814Measure();
SMUARTTurnOn();
delay(10000);
SMUARTMeasure();
delay(10000);
SMUARTMeasure();
delay(1000);
SMUARTMeasure();
delay(1000);
SMUARTMeasure();
delay(1000);
OZONE2CLICKCalibrate();
OZONE2CLICKMeasure();
SDSave();
delay(10000);
RTCBegin();
RTCSleep();
}
void LandingChecker()
{
CurrentTime = millis();
Serial.println(CurrentTime);
if (CurrentTime >= 30000)
{
Serial.println("------------------------------");
Serial.println("AIR PHASE DONE");
Serial.println("------------------------------");
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("STARTING TESTING PHASE");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase1();
}
else
{
Serial.println("------------------------------");
Serial.println("AIR PHASE IN PROGRESS");
Serial.println("------------------------------");
Serial.println(" ");
}
}
void WaitingPhase()
{
digitalWrite(O2Pin, LOW);
digitalWrite(MICS6814Pin, LOW);
digitalWrite(MICSVZ89TEPin, LOW);
digitalWrite(DcPin, LOW);
digitalWrite(D13_led_pin, LOW);
digitalWrite(M_led_pin, LOW);
GyroscopeSleep();
byte seconds = 0;
byte minutes = 00;
byte hours = 00;
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmTime(00, 00, 10);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
rtc.standbyMode();
TerrestrialPhase();
}
void TestingPhase2()
{
Serial.println("------------------------------");
Serial.println("TESTING PHASE DONE");
Serial.println("------------------------------");
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("STARTING TERRESTRIAL PHASE");
Serial.println("------------------------------");
Serial.println(" ");
TerrestrialPhase();
}
void TestingPhase1()
{
if (((gForceX >= 3.60) || (gForceX <= 0.40)) && ((gForceY >= 2.9) && (gForceY <= 3.20)))
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: VERY GOOD");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase2();
}
else if (((gForceX >= 3.30) || (gForceX <= 0.70)) && ((gForceY >= 2.9) && (gForceY <= 3.30)))
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: GOOD");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase2();
}
else if (((gForceX >= 3) || (gForceX <= 1)) && ((gForceY >= 2.9) && (gForceY <= 4)))
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: OK");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase2();
}
else
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: BAD");
Serial.println("------------------------------");
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("TESTING PHASE FAILED");
Serial.println("------------------------------");
Serial.println(" ");
WaitingPhase();
}
}
void SDSave()
{
while(!Serial);
if (!SD.begin(sd_cs_pin))
{
Serial.println("SD card initialization failed!");
return;
}
Serial.println("SD card initialized");
file = SD.open("data.txt", FILE_WRITE); // Open test.txt for write
// Rrite to the file and print info to serial
// print an error to the serial in case it does not succeed
if (file)
{
file.println("--------------------------");
file.println("GyKoVySAT terrestrial data");
file.println("--------------------------");
file.println("OZONE");
file.println(PPMO2);
file.print(" ppm");
file.println(PPBO2);
file.print(" ppb");
file.println(MGM3O2);
file.print(" mg/m³");
file.println("SMOKE PARTICLES STANDART");
file.println(UGM3O2);
file.print(" μg/m³");
file.println(SSmoke1);
file.print(" μg/m³");
file.println(SSmoke2);
file.print(" μg/m³");
file.println(SSmoke3);
file.println("SMOKE PARTICLES ENVIROMENTAL");
file.println(ESmoke1);
file.print(" μg/m³");
file.println(ESmoke2);
file.print(" μg/m³");
file.println(ESmoke3);
file.print(" μg/m³");
file.println("VOC");
file.println(MICS_voc);
file.print(" ppm");
file.println("CO2");
file.println(MICS_eqco2);
file.print(" ppm");
file.println("CO");
file.println(COData);
file.print(" ppm");
file.println("NO2");
file.println(NO2Data);
file.print(" ppm");
file.println("NH3");
file.println(NH3Data);
file.print(" ppm");
file.println("DATA FOR ANALYZATION");
file.println(PPMO2);
file.print(";");
file.print(PPBO2);
file.print(";");
file.print(MGM3O2);
file.print(";");
file.print(UGM3O2);
file.print(";");
file.print(SSmoke1);
file.print(";");
file.print(SSmoke2);
file.print(";");
file.print(SSmoke3);
file.print(";");
file.print(ESmoke1);
file.print(";");
file.print(ESmoke2);
file.print(";");
file.print(ESmoke3);
file.print(";");
file.print(MICS_voc);
file.print(";");
file.print(MICS_eqco2);
file.print(";");
file.print(COData);
file.print(";");
file.print(NO2Data);
file.print(";");
file.print(NH3Data);
file.print(";");
file.print(DataCounter);
file.print(";");
file.close();
DataCounter = DataCounter + 1;
}
else
{
Serial.println("Error opening data.txt for writing");
}
TerrestrialPhase();
}
void setup()
{
// wait for the Arduino serial (on your PC) to connect
// please, open the Arduino serial console (right top corner)
// note that the port may change after uploading the sketch
// COMMENT OUT FOR USAGE WITHOUT A PC!
// while(!Serial);
Serial.println("openCanSat PRO");
Serial.print("Node ");
Serial.print(MYNODEID,DEC);
Serial.println(" ready");
// begin communication with the BME280 on the previously specified address
// print an error to the serial in case the sensor is not found
if (!bme.begin(BME280_ADDRESS_OPEN_CANSAT))
{
isBmeOk = false;
Serial.println("Could not find a valid BME280 sensor, check wiring!");
return;
}
// begin communication with the INA219
ina219.begin();
// check of Gps is connected
Wire.beginTransmission(0x42); // 42 is addres of GPS
int error = Wire.endTransmission();
if (error != 0)
{
isGpsConnected = false;
}
// begin communication with gps
gps.begin();
// Uncomment when you want to see debug prints from GPS library
// gps.debugPrintOn(57600);
if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
{
isRadioOk = false;
Serial.println("RFM69HW initialization failed!");
}
else
{
radio.setFrequency(FREQUENCYSPECIFIC);
radio.setHighPower(true); // Always use this for RFM69HW
}
pinMode(D13_led_pin, OUTPUT);
pinMode(DcPin, OUTPUT);
pinMode(MICS6814Pin, OUTPUT);
pinMode(MICSVZ89TEPin, OUTPUT);
pinMode(O2Pin, OUTPUT);
GyroscopeTurnOn();
}
void loop()
{
cansatdata.messageId = idCounter;
GyroscopeMeasure();
LandingChecker();
Serial.println("MessageId = " + static_cast<String>(cansatdata.messageId));
cansatdata.temperature = 0;
cansatdata.pressure = 0;
cansatdata.altitude = 0;
if(isBmeOk)
{
cansatdata.temperature += bme.readTemperature();
cansatdata.pressure += bme.readPressure() / 100.0F;
cansatdata.altitude += bme.readAltitude(SEALEVELPRESSURE_HPA);
cansatdata.humidity_bme280 = bme.readHumidity();
}
Serial.println("Temperature = " + static_cast<String>(cansatdata.temperature) + " *C");
Serial.println("Pressure = " + static_cast<String>(cansatdata.pressure) + " Pa");
Serial.println("Approx altitude = " + static_cast<String>(cansatdata.altitude) + " m");
Serial.println("Humidity = " + static_cast<String>(cansatdata.humidity_bme280) + " %");
// read values from INA219 into structure
cansatdata.voltage_shunt = ina219.getShuntVoltage_mV();
cansatdata.voltage_bus = ina219.getBusVoltage_V();
cansatdata.current_mA = ina219.getCurrent_mA();
cansatdata.voltage_load = cansatdata.voltage_bus + (cansatdata.voltage_shunt / 1000);
Serial.println("Shunt Voltage: " + static_cast<String>(cansatdata.voltage_shunt) + " mV");
Serial.println("Bus Voltage: " + static_cast<String>(cansatdata.voltage_bus) + " V");
Serial.println("Current: " + static_cast<String>(cansatdata.current_mA) + " mA");
Serial.println("Load Voltage: " + static_cast<String>(cansatdata.voltage_load) + " V");
// Initialize GPS
cansatdata.year = 0;
cansatdata.month = 0 ;
cansatdata.day = 0;
cansatdata.hour = 0;
cansatdata.minute = 0;
cansatdata.sec = 0;
cansatdata.latitude = 0;
cansatdata.longitude = 0;
cansatdata.num_of_satelites = 0;
// save start time in millisec
uint32_t start = millis();
// END LED BLINK
digitalWrite(D13_led_pin, LOW);
pinMode(M_led_pin, INPUT);
// END LED BLINK
if(isGpsConnected)
{
if (gps.scan(250))
{
cansatdata.year = gps.getYear();
cansatdata.month = gps.getMonth();
cansatdata.day = gps.getDay();
cansatdata.hour = gps.getHour();
cansatdata.minute = gps.getMinute();
cansatdata.sec = gps.getSecond();
cansatdata.latitude = gps.getLat();
cansatdata.longitude = gps.getLon();
cansatdata.num_of_satelites = gps.getNumberOfSatellites();
Serial.println(String("Time to find fix: ") + (millis() - start) + String("ms"));
Serial.println(String("Datetime: ") + String(cansatdata.year) + "/"+ String(cansatdata.month) + "/"+ String(cansatdata.day) + " " + String(cansatdata.hour) + ":"+ String(cansatdata.minute) + ":"+ String(cansatdata.sec));
Serial.println(String("Lat: ") + String(cansatdata.latitude, 7));
Serial.println(String("Lon: ") + String(cansatdata.longitude, 7));
Serial.println(String("Num of sats: ") + String(cansatdata.num_of_satelites));
Serial.println();
}
else
{
Serial.println("Gps have no satelit to fix.");
}
}
// RFM69HW
cansatdata.rssi = 0;
if(isRadioOk)
{
cansatdata.rssi = radio.RSSI;
Serial.println("Signal = " + static_cast<String>(radio.RSSI));
radio.send(TONODEID, (const void*)&cansatdata, sizeof(cansatdata));
}
Serial.println();
// START LED hart beat
pinMode(M_led_pin, OUTPUT);
digitalWrite(D13_led_pin, HIGH);
digitalWrite(M_led_pin, HIGH);
// START LED hart beat
if(!isGpsConnected)
{
delay(200);
}
idCounter ++;
}
most SPI interfaces can be placed in a 'loopback' mode, which makes it easy for the code to check the activity to verify the transmitted/received data
regarding:
if (error != 0)
{
isGpsConnected = false;
}
// begin communication with gps
gps.begin();
should not be trying to communicate with the GPS if no GPS connected. suggest:
if (error != 0)
{
isGpsConnected = false;
return;
}
else
{
// begin communication with gps
gps.begin();
}
Related
I am using the T-SIM7600E-L1C 4G LTE ESP32 from TTGO, My problem is that it won't connect to the internet? Here is the code that I am using.
// Arduino file start here
#define TINY_GSM_MODEM_SIM7600
#define SerialMon Serial
//#define TINY_GSM_DEBUG SerialMon
#include <HCSR04.h>
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701
HardwareSerial SerialAT(1);
#if !defined(TINY_GSM_RX_BUFFER)
#define TINY_GSM_RX_BUFFER 650
#endif
#define TINY_GSM_YIELD() { delay(2); }
const char apn[] = "Vodacom APN";
const char gprsUser[] = "";
const char gprsPass[] = "";
const char server[] = "";
const char resource[] = "";
const int port = 80;
unsigned long timeout;
const int trigPin = 25;
const int echoPin = 26;
long duration;
int distance;
#include <TinyGsmClient.h>
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
void setup()
{
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
SerialMon.begin(115200);
delay(10);
SerialMon.println("Wait...");
SerialAT.begin(115200,SERIAL_8N1,26,27, false);
delay(600);
SerialMon.println("Initializing modem...");
}
void loop()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
modem.restart();
SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork()) {
SerialMon.println(" fail");
delay(1000);
return;
}
SerialMon.println(" success");
if (modem.isNetworkConnected())
{
SerialMon.println("Network connected");
}
SerialMon.print(F("Connecting to "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass))
{
SerialMon.println(" fail");
delay(1000);
return;
}
SerialMon.println(" success");
if (modem.isGprsConnected())
{
SerialMon.println("GPRS connected");
}
if (!client.connect(server, port))
{
SerialMon.println(" fail");
}
SerialMon.println("Performing HTTP POST request...");
String httpRequestData = "key=a#4K%3&distance="+ String(distance) +"";
client.print(String("POST ") + resource + " HTTP/1.1\r\n");
client.print(String("Host: ") + server + "\r\n");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(httpRequestData.length());
client.println();
client.println(httpRequestData);
timeout = millis();
while (client.connected() && millis() - timeout < 10000L)
{
while (client.available())
{
char c = client.read();
SerialMon.print(c);
timeout = millis();
}
}
SerialMon.println();
client.stop();
SerialMon.println(F("Server disconnected"));
modem.gprsDisconnect();
SerialMon.println(F("GPRS disconnected"));
}
The fail message:
et.Rչ� 8�016 0�'&&��SH�HH���0� (POWE���%UMQ�,boot:�� (DO���} =OT(UAR�UART1iE%=}I%�REO_V2JJC�W�ѥng for"�ݹ����5ets Jun 8 2016 00:22:57rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)configsip: 0, SPIWP:0xeeclk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00mode:DIO, clock div:1load:0x3fff0018,len:4load:0x3fff001c,len:1216ho 0 tail 12 room 4load:0x40078000,len:9720ho 0 tail 12 room 4load:0x40080400,len:6352entry 0x400806b8Wait
...Initializing modem
...Waiting for network
...fail
Exists a lot of problems with mobile that you need to verify when you use an internet modem in your Arduino project. The problems involve for example, the lack of current (you need to give 2A of current to work properly), the dupont cables/jumpers couldn't work sometimes (the connection cables need to be short), and the APN, when I worked with this kind of SIMCOM modems I needed to buy a telemetry SIM card too.
I am using an esp32 to send some environmental data, such as temperature, humidity, pressure, pm2.5, and TVOV to a thinkspeak server. This works sometimes for a few hours and then it suddenly stops sending data. It also seems to be a bit random on when it stops. Sometimes it works just a few minutes and sometimes much longer. My code is probably is a great mess as I combined the codes from different sensors. Can anybody check the code and maybe see what my ESP32 suddenly stops sending data?
Code:
#include <WiFi.h>
#include <Wire.h>
#include "Adafruit_SGP30.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define LENG 31 //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];
Adafruit_SGP30 sgp;
int PM01Value=0; //define PM1.0 value of the air detector module
int PM2_5Value=0; //define PM2.5 value of the air detector module
int PM10Value=0; //define PM10 value of the air detector module
float h, t, p, pin, dp;
char temperatureFString[6];
char dpString[6];
char humidityString[6];
char pressureString[7];
char pressureInchString[6];
/* return absolute humidity [mg/m^3] with approximation formula
* #param temperature [°C]
* #param humidity [%RH]
*/
uint32_t getAbsoluteHumidity(float t, float h) {
//approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
const float absoluteHumidity = 216.7f * ((h / 100.0f) * 6.112f * exp((17.62f * t) / (243.12f + t)) / (273.15f + t)); // [g/m^3]
const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity); // [mg/m^3]
return absoluteHumidityScaled;
}
char checkValue(unsigned char *thebuf, char leng)
{
char receiveflag=0;
int receiveSum=0;
for(int i=0; i<(leng-2); i++){
receiveSum=receiveSum+thebuf[i];
}
receiveSum=receiveSum + 0x42;
if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1])) //check the serial data
{
receiveSum = 0;
receiveflag = 1;
}
return receiveflag;
}
int transmitPM01(unsigned char *thebuf)
{
int PM01Val;
PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
return PM01Val;
}
//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
int PM2_5Val;
PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
return PM2_5Val;
}
//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
int PM10Val;
PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module
return PM10Val;
}
String apiKey = "6HNZHJJA9KD2PM43";
// replace with your routers SSID
const char* ssid = "XXX";
const char* password = "XXX";
const char* server = "api.thingspeak.com";
WiFiClient client;
Adafruit_BME280 bme; // I2C
void setup() {
Serial.begin(9600);
delay(10);
Serial.println();
Wire.begin();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Printing the ESP IP address
Serial.println(WiFi.localIP());
if (!bme.begin(0x76))
{
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
if (! sgp.begin()){
Serial.println("Could not find a valid SGP30 sensor, check wiring!");
while (1);
}
Serial.print("Found SGP30 serial #");
Serial.print(sgp.serialnumber[0], HEX);
Serial.print(sgp.serialnumber[1], HEX);
Serial.println(sgp.serialnumber[2], HEX);
// If you have a baseline measurement from before you can assign it to start, to 'self-calibrate'
//sgp.setIAQBaseline(0x8E68, 0x8F41); // Will vary for each sensor!
}
int counter = 0;
void loop() {
// If you have a temperature / humidity sensor, you can set the absolute humidity to enable the humditiy compensation for the air quality signals
sgp.setHumidity(getAbsoluteHumidity(t, h));
if (! sgp.IAQmeasure()) {
Serial.println("Measurement failed");
return;
}
Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print(" ppb\t");
Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.println(" ppm");
if (! sgp.IAQmeasureRaw()) {
Serial.println("Raw Measurement failed");
return;
}
counter++;
if (counter == 20) {
counter = 0;
uint16_t TVOC_base, eCO2_base;
if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) {
Serial.println("Failed to get baseline readings");
return;
}
Serial.print("****Baseline values: eCO2: 0x"); Serial.print(eCO2_base, HEX);
Serial.print(" & TVOC: 0x"); Serial.println(TVOC_base, HEX);
}
h = bme.readHumidity();
t = (bme.readTemperature()-2);
dp = t-0.36*(100.0-h);
p = bme.readPressure()/100.0F;
pin = 0.02953*p;
dtostrf(t, 5, 1, temperatureFString);
dtostrf(h, 5, 1, humidityString);
dtostrf(p, 6, 1, pressureString);
dtostrf(pin, 5, 2, pressureInchString);
dtostrf(dp, 5, 1, dpString);
Serial.print("Temperature = ");
Serial.println(temperatureFString);
Serial.print("Humidity = ");
Serial.println(humidityString);
Serial.print("Pressure = ");
Serial.println(pressureString);
if(Serial.find(0x42)){ //start to read when detect 0x42
Serial.readBytes(buf,LENG);
if(buf[0] == 0x4d){
if(checkValue(buf,LENG)){
PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
}
}
}
static unsigned long OledTimer=millis();
if (millis() - OledTimer >=1000)
{
OledTimer=millis();
}
Serial.print("PM1.0: ");
Serial.print(PM01Value);
Serial.println(" ug/m3");
Serial.print("PM2.5: ");
Serial.print(PM2_5Value);
Serial.println(" ug/m3");
Serial.print("PM10 : ");
Serial.print(PM10Value);
Serial.println(" ug/m3");
Serial.println();
Serial.println("...............................................");
if (client.connect(server,80)) // "184.106.153.149" or api.thingspeak.com
{
String postStr = apiKey;
postStr +="&field1=";
postStr += String(temperatureFString);
postStr +="&field2=";
postStr += String(humidityString);
postStr +="&field3=";
postStr += String(pressureString);
postStr +="&field4=";
postStr += String(PM01Value);
postStr +="&field5=";
postStr += String(PM2_5Value);
postStr +="&field6=";
postStr += String(PM10Value);
postStr +="&field7=";
postStr += String(sgp.eCO2);
postStr +="&field8=";
postStr += String(sgp.TVOC);
postStr += "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
}
delay(16000);
client.stop();
}
We have built a drone controller using C++ and an Arduino ESP32 module. We have achieved connection to a Tello Drone and can control it successfully. However, now we want to connect our controller to a javafx program that receives input and then draws on a canvas in scene builder.
Meanwhile the problem is that we can't seem to connect our controller through PacketSender. We have attached our code, including the previous built that enabled connection with a drone.
The big question is how to send the messages between two programs and initiate our virtual depiction of our drone on a canvas - instead of the actual physical one.
The issue seems to be in case 1, line 190, where we connected controller to actual drone, but now have to write up a new connection somehow.
#include <Arduino.h>
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "OnePlus 7 Pro";
const char * password = "hej12345";
//Connect button variables (Command)
int inPinLand = 18;
int valLand = 0;
//Ultra sonic sensor variables
#define trigPin 2
#define echoPin 21
//Land button variables (Land)
int inPin = 25;
int val = 0;
//Instantiate specific drone
const char * networkName = "TELLO-59F484";
const char * networkPswd = "";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const char * udpAddress = "10.60.0.227";
const int udpPort = 7000;
boolean connected = false;
char fromTello[256];
unsigned long timer;
//static const byte glyph[] = { B00010000, B00110100, B00110000, B00110100, B00010000 };
//static PCD8544 lcd;
uint8_t state = 0;
//Controller movement variables
int pitch = 0;
int roll = 0;
int yaw = 0;
int throttle = 0;
char cmd[256];
AsyncUDP udp;
void setup() {
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while (1) {
delay(1000);
}
}
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(inPin, INPUT);
pinMode(inPinLand, INPUT);
//LCD screen initialization
//lcd.begin(84, 48);
Serial.begin(9600);
//pinMode(trigPin, OUTPUT);
//pinMode(echoPin, INPUT);
//pinMode(BL, OUTPUT);
//digitalWrite(BL, HIGH);
if (udp.listen(7000)) {
Serial.print("UDP Listening on IP: ");
Serial.println(WiFi.localIP());
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()
? "Broadcast"
: packet.isMulticast() ? "Multicast" : "Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
// reply to the client/sender
packet.printf("Got %u bytes of data", packet.length());
});
}
// Send unicast
// udp.print("Hello Server!");
// udp.
}
//WiFi connection function
void connectToWiFi(const char * ssid, const char * pwd) {
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//Drone connection function
void TelloCommand(char *cmd) {
//only send data when connected
if (connected) {
//Send a packet
//udp.beginPacket(udpAddress, udpPort); OUTDATED has new name with ASync
udp.printf(cmd);
//udp.endPacket(); OUTDATED has new name with ASync
Serial.printf("Send [%s] to Tello.\n", cmd);
}
}
void sendMessage(String msg){
udp.writeTo((const uint8_t *)msg.c_str(), msg.length(),
IPAddress(169, 254, 107, 16), 4000);
}
void loop() {
delay(5000);
// Send broadcast on port 4000
udp.broadcastTo("Anyone here?", 4000);
// Serial.println("waiting for udp message...");
int x = 100;
int y = 100;
sendMessage("init " + String(x) + " " + String(y));
}
void loop() {
long duration, distance;
val = digitalRead(inPin); // read input value
//Ultra sonic sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
//LCD screen line 2
// lcd.setCursor(0, 1);
// lcd.print(distance, DEC);
//State machine that connects the drone to WiFi and the controller
switch (state)
{
case 0: //Idle not connected
//LCD screen line 1
//lcd.setCursor(0, 0);
//lcd.print("Controller");
if (val == HIGH)
{
state = 1;
connectToWiFi(networkName, networkPswd);
timer = millis() + 5000;
}
break;
case 1: //Trying to connect
if (WiFi.status() == WL_CONNECTED)
{
Serial.print("Connected to: ");
Serial.println(networkName);
udp.begin(WiFi.localIP(), udpPort);
connected = true;
TelloCommand("command");
timer = millis() + 2000;
state = 2;
}
if (millis() > timer)
{
state = 0;
}
break;
case 2: //Connected on ground
//lcd.setCursor(0, 0);
//lcd.print("Connected ");
if (WiFi.status() != WL_CONNECTED)
{
WiFi.disconnect(true);
Serial.println("Disconnected");
state = 0;
}
if (distance < 10)
{
TelloCommand("takeoff");
timer = millis() + 1000;
state = 3;
Serial.println("takeoff");
}
break;
case 3: //In air
//lcd.setCursor(0, 0);
//lcd.print("In air ");
if (millis() > timer)
{
timer = millis() + 20;
pitch = map(analogRead(34) - 1890, -2000, 2000, -100, 100);
roll = map(analogRead(35) - 1910, -2000, 2000, -100, 100);
throttle = map(analogRead(33) - 1910, -2000, 2000, -100, 100);
yaw = map(analogRead(32) - 1910, -2000, 2000, -100, 100);
sprintf(cmd, "rc %d %d %d %d", roll, pitch, throttle, yaw);
TelloCommand(cmd);
}
if (val == HIGH) {
TelloCommand("land");
timer = millis() + 1000;
state = 0;
Serial.println("land");
}
break;
}
delay(200);
}
This question already exists:
missing sleep mode after disconnecting from PC [closed]
Closed 2 years ago.
I am having an issue with my satellite project. When I disconnect my device from the PC, sleep mode does not work - I suppose it is because somewhere in the code I have function if, that includes (Serial.available()). But I am not sure, so that is, why I need your help. I tell you again, if the device is connected to PC everything works normally, problems will start happening after disconnecting it from PC.
Thank you for your answers!
PS: If you do not understand the code - like if you miss something, do not worry, I deleted only the parts, that are not used when device goes to sleep. If you have some problem instead, please complain with theese "ultra clever - hawking cannot even compare with their intelligence" moderators.
Here is the code:
#include <Adafruit_BME280.h> // include Adafruit BME280 library
#include <Adafruit_INA219.h> // include INA219
#include <SD.h> // include Arduino SD library
#include "Open_Cansat_GPS.h"
#include <RTCZero.h>
//include our new sensors
#include <MICS6814.h>
#include <MICS-VZ-89TE.h>
#include "MQ131.h"
#include <Wire.h>
#include <SPI.h>
#include "RFM69.h" // include RFM69 library
// Local
#define PC_BAUDRATE 115200
#define MS_DELAY 0 // Number of milliseconds between data sending and LED signalization
#define LED_DELAY 100
#define Serial SerialUSB
RTCZero rtc;
// RFM69
#define NETWORKID 0
#define MYNODEID 1
#define TONODEID 2
#define FREQUENCY RF69_433MHZ
#define FREQUENCYSPECIFIC 433000000 // Should be value in Hz, now 433 Mhz will be set
#define CHIP_SELECT_PIN 43 //radio chip select
#define INTERUP_PIN 9 //radio interrupt
// BME280 SETTING
#define BME280_ADDRESS_OPEN_CANSAT 0x77
#define SEALEVELPRESSURE_HPA 1013.25
//define our sensor pins
//MICS6814
#define PIN_CO 0
#define PIN_NO2 0
#define PIN_NH3 0
#define MICS6814Pin 6
//OZONE2CLICK
const byte pinSS = 2; //cs pin
const byte pinRDY = 12;
const byte pinSCK = 13;
const byte O2Pin = 10;
//SMUART
bool flag1 = false;
bool flag2 = false;
byte rxData[30];
byte one, two;
#define DcPin 8
//MICSVZ89TE
#define MICSVZ89TEPin 7
int datas [7];
bool MICS_status;
int MICS_voc;
int MICS_eqco2;
//PHASES
float CurrentTime;
const byte day = 17;
const byte month = 11;
const byte year = 15;
//our sensors settings
//MICS6814
MICS6814 gas(PIN_CO, PIN_NO2, PIN_NH3);
//gyroscope
long accelX, accelY, accelZ;
float gForceX, gForceY, gForceZ;
long gyroX, gyroY, gyroZ;
float rotX, rotY, rotZ;
// SD card
#define sd_cs_pin 35 // set SD's chip select pin (according to the circuit)
// create object 'rf69' from the library, which will
// be used to access the library methods by a dot notation
RFM69 radio(CHIP_SELECT_PIN, INTERUP_PIN, true);
// define our own struct data type with variables; used to send data
typedef struct
{
int16_t messageId;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t sec;
float longitude;
float latitude;
uint8_t num_of_satelites;
float temperature;
float pressure;
float altitude;
float humidity_bme280;
float voltage_shunt;
float voltage_bus;
float current_mA;
float voltage_load;
int16_t rssi;
} messageOut;
messageOut cansatdata; //create the struct variable
// create object 'bme' from the library, which will
// be used to access the library methods by a dot notation
Adafruit_BME280 bme;
// create object 'ina219' from the library with address 0x40
// (according to the circuit, which will be used to access the
// library methods by a dot notation
Adafruit_INA219 ina219(0x40);
// create object 'gps' from the library
OpenCansatGPS gps;
// SD card
File file; // SD library variable
// LEDS
#define D13_led_pin 42 // D13 LED
#define M_led_pin 36 // MLED
// Local variables
int idCounter = 1;
bool isBmeOk = true;
bool isSdOk = true;
bool isRadioOk = true;
bool isGpsConnected = true;
void RTCBegin ()
{
rtc.begin();
}
void RTCSleep ()
{
digitalWrite(O2Pin, LOW);
digitalWrite(MICS6814Pin, LOW);
digitalWrite(MICSVZ89TEPin, LOW);
digitalWrite(DcPin, LOW);
digitalWrite(D13_led_pin, LOW);
digitalWrite(M_led_pin, LOW);
GyroscopeSleep();
delay(1000);
byte seconds = 0;
byte minutes = 00;
byte hours = 00;
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmTime(00, 00, 10);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
rtc.standbyMode();
delay(1000);
TerrestrialPhase();
// Sleep until next alarm match
}
void TerrestrialPhase()
{
Serial.begin(9600);
Serial.println("------------------------------");
Serial.println("TERRESTRIAL PHASE IN PROGRESS");
Serial.println("------------------------------");
Serial.println(" ");
digitalWrite(DcPin, HIGH);
digitalWrite(MICS6814Pin, HIGH);
digitalWrite(MICSVZ89TEPin, HIGH);
digitalWrite(O2Pin, HIGH);
delay(2000);
MICSVZ89TEMeasure();
MICSVZ89TEMeasure();
MICSVZ89TEMeasure();
MICSVZ89TEMeasure();
MICS6814Calibrate();
MICS6814Measure();
SMUARTTurnOn();
delay(10000);
SMUARTMeasure();
delay(10000);
SMUARTMeasure();
delay(1000);
SMUARTMeasure();
delay(1000);
SMUARTMeasure();
delay(10000);
SDSave();
delay(1000);
}
void LandingChecker()
{
CurrentTime = millis();
Serial.println(CurrentTime);
if (CurrentTime >= 3000)
{
Serial.println("------------------------------");
Serial.println("AIR PHASE DONE");
Serial.println("------------------------------");
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("STARTING TESTING PHASE");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase1();
}
else
{
Serial.println("------------------------------");
Serial.println("AIR PHASE IN PROGRESS");
Serial.println("------------------------------");
Serial.println(" ");
}
}
void WaitingPhase()
{
Serial.println("------------------------------");
Serial.println("WAITING PHASE IN PROGRESS");
Serial.println("------------------------------");
Serial.println(" ");
digitalWrite(O2Pin, LOW);
digitalWrite(MICS6814Pin, LOW);
digitalWrite(MICSVZ89TEPin, LOW);
digitalWrite(DcPin, LOW);
digitalWrite(D13_led_pin, LOW);
digitalWrite(M_led_pin, LOW);
GyroscopeSleep();
byte seconds = 0;
byte minutes = 00;
byte hours = 00;
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmTime(00, 00, 10);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
rtc.standbyMode();
TerrestrialPhase();
}
void TestingPhase2()
{
Serial.println("------------------------------");
Serial.println("TESTING PHASE DONE");
Serial.println("------------------------------");
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("STARTING TERRESTRIAL PHASE");
Serial.println("------------------------------");
Serial.println(" ");
TerrestrialPhase();
}
void TestingPhase1()
{
if (((gForceX >= 3.60) || (gForceX <= 0.40)) && ((gForceY >= 2.9) && (gForceY <= 3.20)))
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: VERY GOOD");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase2();
}
else if (((gForceX >= 3.30) || (gForceX <= 0.70)) && ((gForceY >= 2.9) && (gForceY <= 3.30)))
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: GOOD");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase2();
}
else if (((gForceX >= 3) || (gForceX <= 1)) && ((gForceY >= 2.9) && (gForceY <= 4)))
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: OK");
Serial.println("------------------------------");
Serial.println(" ");
TestingPhase2();
}
else
{
Serial.println("------------------------------");
Serial.println("SATELITE POSITION: BAD");
Serial.println("------------------------------");
Serial.println(" ");
Serial.println("------------------------------");
Serial.println("TESTING PHASE FAILED");
Serial.println("------------------------------");
Serial.println(" ");
WaitingPhase();
}
}
void SDSave()
{
while(!Serial);
if (!SD.begin(sd_cs_pin))
{
Serial.println("SD card initialization failed!");
return;
}
Serial.println("SD card initialized");
file = SD.open("data.txt", FILE_WRITE); // Open test.txt for write
// Rrite to the file and print info to serial
// print an error to the serial in case it does not succeed
if (file)
{
file.println(" ");
file.println("--------------------------");
file.println("GyKoVySAT TERRESTRIAL DATA");
file.println("--------------------------");
file.println("OZONE");
file.print(PPMO2);
file.println(" ppm");
file.print(PPBO2);
file.println(" ppb");
file.print(MGM3O2);
file.println(" mg/m³");
file.print(UGM3O2);
file.println(" ug/m³");
file.println("SMOKE PARTICLES STANDART");
file.print(SSmoke1);
file.println(" μg/m³");
file.print(SSmoke2);
file.println(" μg/m³");
file.print(SSmoke3);
file.println(" μg/m³");
file.println("SMOKE PARTICLES ENVIROMENTAL");
file.print(ESmoke1);
file.println(" μg/m³");
file.print(ESmoke2);
file.println(" μg/m³");
file.print(ESmoke3);
file.println(" μg/m³");
file.println("VOC");
file.print(MICS_voc);
file.println(" ppm");
file.println("CO2");
file.print(MICS_eqco2);
file.println(" ppm");
file.println("CO");
file.print(COData);
file.println(" ppm");
file.println("NO2");
file.print(NO2Data);
file.println(" ppm");
file.println("NH3");
file.print(NH3Data);
file.println(" ppm");
file.close();
DataCounter = DataCounter + 1;
}
else
{
Serial.println("Error opening data.txt for writing");
}
delay(1000);
RTCBegin();
RTCSleep();
delay(1000);
TerrestrialPhase();
}
I'm using an Arduino Uno with an Adafruit Motor Shield (v2) in order to power and control a motor and a LIS3DH accelerometer. With a simpler code in which the motor just goes forward for a certain number of pulses (output by the encoder), the identical function for the accelerometer outputs correct values. The code is shown below.
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_Sensor.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#define pi 3.14159
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
float distance = 30;
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
unsigned int pulsesperturn = 56 * 64 / 2 ;
float circumference = 5.25 * 3.14159;
int pulses;
//int count = 0;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void) {
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
//
}
void loop() {
// // }
// myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
// myMotor->run(FORWARD);
// delay(2500);
// myMotor->setSpeed(0);
// // right = 0;
// delay(1000);
// // right = 1;
// myMotor->run(BACKWARD);
// myMotor->setSpeed(255);
// delay(2500);
// myMotor->setSpeed(0);
// // right = 0;
// delay(1000);
// // right = 1;
myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
if (pulsesperturn <= pulses ) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
myMotor->setSpeed(0);
stoppedAccel();
pulses = 0;
}
// Then print out the raw data
// Serial.print("X: "); Serial.print(lis.x);
// Serial.print(" \tY: "); Serial.print(lis.y);
// Serial.print(" \tZ: "); Serial.print(lis.z);
// for (int a = 1; a < 20; a = a + 1) {
// lis.read(); // get X Y and Z data at once
// sensors_event_t event;
// lis.getEvent(&event);
//
// /* Display the results (acceleration is measured in m/s^2) */
// // Serial.print(" \tAngle: "); Serial.print(angle);
// //
// // Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// // Serial.println(" m/s^2 ");
//
// Serial.println();
// //
// // char buffer[5];
// // Serial.print("#S|WRITEDATA|[");
// // Serial.print(angle); // accels
// // Serial.println("]#");
//
// // WriteAccel();
// delay(10);
// }
// myMotor->run(FORWARD);
//
// myMotor->run(RELEASE);
// myMotor->setSpeed(255);
// if (distance / circumference * pulsesperturn <= pulses) {
// myMotor->setSpeed(0);
// delay(2500);
// }
// myMotor->setSpeed(255);
// myMotor->run(FORWARD);
// pulses = 0;
Serial.print("pulses = ");
Serial.println(pulses);
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
/* Or....get a new sensor event, normalized */
}
void counter()
{
pulses++;
}
void stoppedAccel()
{
for (int a = 1; a < 150; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
float angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(10);
}
}
In this code, which runs the motor forward for a distance 6 times and then runs it backward for the same distance it went forward, the motor runs correctly and the accelerometer says that it has been found but it outputs exclusively null values.
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159
//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void)
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
// myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}
void loop() {
motorDirection();
}
void counter()
{
pulses++;
}
void bcounter()
{
b++;
}
void motorDirection()
{
while (b < 6) {
myMotor->run(FORWARD);
readInt();
if (500 * conversion <= pulses) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
pulses = 0;
bcounter();
if (b == 6) {
stoppedAccel();
}
delay(1500);
}
// break;
}
while (b == 6) {
myMotor->run(BACKWARD);
readInt();
if (500 * b <= pulses) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
bcounter();
stoppedAccel();
pulses = 0;
delay(500);
break;
}
}
while (b > 6) {
b = 0;
break;
}
}
// 169 forward per 1000, 171 backward
void stoppedAccel()
{
for (int a = 1; a < 150; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
float angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(100);
}
}
void readInt()
{
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
Serial.print("pulses = ");
Serial.println(pulses);
}
I have tried various things but I have little background in CS, especially in C++, so my attempts haven't been fruitful. Any advice would be helpful.
The issue was using delay(). How exactly the hardware works, I'm not sure, but I believe blocking it in such a way threw off the hardware so that it was outputting null. Below is the corrected code using millis().
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159
float angle;
const long interval = 1000;
unsigned long previousMillis;
//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void)
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
// myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}
void loop() {
motorDirection();
// stoppedAccel();
}
void counter()
{
pulses++;
}
void bcounter()
{
b++;
}
void motorDirection()
{
//serial.write
while (b < 6) {
myMotor->run(FORWARD);
readInt();
if (500 * conversion <= pulses) {
myMotor->run(RELEASE);
bcounter();
previousMillis = millis();
timing();
// previousMillis = currentMillis;
pulses = 0;
if (b == 6) {
stoppedAccel();
}
}
break;
}
while (b == 6) {
myMotor->run(BACKWARD);
readInt();
if (500 * b <= pulses) {
myMotor->run(RELEASE);
pulses = 0;
bcounter();
stoppedAccel();
break;
}
}
while (b > 6) {
b = 0;
break;
}
}
// 169 forward per 1000, 171 backward
void stoppedAccel()
{
for (int a = 1; a < 200; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(10);
}
}
void readInt()
{
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
Serial.print("pulses = ");
Serial.println(pulses);
}
void timing()
{
while (millis() - previousMillis <= interval) {
myMotor->run(RELEASE);
}
}