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);
}
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’m trying to build a feeder machine on a pig farm by using the Infrared photoelectric switch Sensor E18-D80NK to control relay then send notifications to line and mqtt broker when it’s working. I have been testing for 2 days, it’s working normal, but third day, it’s not responding then I just press reset so it’s working again.
I’m wondering it may cause by board cause it happen only one of four boards that I tasted or may be my code cause I was confused why output to line send “connected” so many times it’s should sent only one time when connected to wifi, so I’m not sure pls help.
Question
Why board not responding after working normal for a while.
Why out output to line send "connected" more than one cause I put in void setup()
Pictures
Last line output since working
All code
extra library line notification library
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <TridentTD_LineNotify.h>
const char* ssid = "Artnaseaw-2.4G";
const char* password = "0812667120";
const char* mqttUser = "****";
const char* mqttPassword = "****";
const char* mqttServer = "******";
const int mqttPort = *****;
const char* linetoken = "********";
long lastMsg = 0;
String DataString;
int lastL=0;
WiFiClient espClient;
PubSubClient client(espClient);
const int ACTION = D8;
const int SENSOR = D2;
const char* host = "maker.ifttt.com";
const char *privateKey = "******";
const char *event = "*****";
String value1, value2;
String postData = "";
String MachineID="A01";
void setup() {
Serial.begin(115200);
pinMode(SENSOR, INPUT_PULLUP);
pinMode(ACTION, OUTPUT);
digitalWrite(SENSOR, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("test", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.subscribe("command");
LINE.setToken(linetoken);
LINE.notify("Connected");
Serial.println("line send connected");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
client.loop();
delay(5000);
int sensorValue = digitalRead(SENSOR);
long now = millis();
if (now - lastMsg > 60000)
{
lastMsg = now;
int sensorValue = digitalRead(SENSOR);
if (sensorValue == LOW){
Serial.println(" === Obstacle detected");
Serial.print(" realy OFF ");
digitalWrite(ACTION,LOW);
} else {
LINE.notify("send data to line ---working");
Serial.println(" === All Clear");
Serial.println(" relay ON ");
digitalWrite(ACTION,HIGH);
sendMessageToIFTTT();
sendSensorToMQTT();
}
}
}
void sendSensorToMQTT(){
char msg[100];
int count = 1;
DataString = "e18,location=test detest="+String(count);
DataString.toCharArray(msg, 100);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("e18", msg);
}
void sendMessageToIFTTT(){
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
String url = "/trigger/";
url += event;
url += "/with/key/";
url += privateKey;
value1 = "Worked";
value2 = "1";
genJSonObject();
Serial.print("Requesting URL: ");
Serial.println(url);
Serial.println(postData);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n");
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(postData.length());
client.println();
client.println(postData);
client.println("Connection: close\r\n\r\n");
while (client.connected())
{
if (client.available())
{
String line = client.readStringUntil('\r');
Serial.print(line);
} else {
// No data yet, wait a bit
delay(50);
};
}
}
void genJSonObject()
{
postData = "{";
postData.concat("\"value1\":\"");
postData.concat(value1);
postData.concat("\",");
postData.concat("\"value2\":\"");
postData.concat(value2);
postData.concat("\"}");
}
Try to connect to another mqtt broker and see if it connects more than once in there too. If it happens the problem might be in the sketch. Otherwise, the cause may be with the IFTTT service.
I am going to establish a mqtt connection to aws. DHT senstor reading must be sent from esp32 to aws. How can I fix the error RC = -1 when connecting esp32 to aws. I receive this error in serial monitor :
Attempting MQTT connection...failed, rc=-1 try again in 5 seconds
What can be the reaon?
My code is as follows:
#include "SPIFFS.h"
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <DHT.h> // library for getting data from DHT
// Enter your WiFi ssid and password
const char* ssid = "TP-Link_DBCA"; //Provide your SSID
const char* password = "44388027"; // Provide Password
const char* mqtt_server = "a3k7086cinb3bt-ats.iot.us-west-2.amazonaws.com"; // Relace with your MQTT END point
const int mqtt_port = 8883;
String Read_rootca;
String Read_cert;
String Read_privatekey;
#define BUFFER_LEN 256
long lastMsg = 0;
char msg[BUFFER_LEN];
int Value = 0;
byte mac[6];
char mac_Id[18];
int count = 1;
WiFiClientSecure espClient;
PubSubClient client(espClient);
#define DHTPIN 4 //pin where the DHT22 is connected
DHT dht(DHTPIN, DHT11);
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP32-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("ei_out", "hello world");
// ... and resubscribe
client.subscribe("ei_in");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
dht.begin();
// initialize digital pin LED_BUILTIN as an output.
pinMode(2, OUTPUT);
setup_wifi();
delay(1000);
//=============================================================
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
//=======================================
//Root CA File Reading.
File file2 = SPIFFS.open("/AmazonRootCA1.pem", "r");
if (!file2) {
Serial.println("Failed to open file for reading");
return;
}
Serial.println("Root CA File Content:");
while (file2.available()) {
Read_rootca = file2.readString();
Serial.println(Read_rootca);
}
//=============================================
// Cert file reading
File file4 = SPIFFS.open("/certificate.pem.crt.txt", "r");
if (!file4) {
Serial.println("Failed to open file for reading");
return;
}
Serial.println("Cert File Content:");
while (file4.available()) {
Read_cert = file4.readString();
Serial.println(Read_cert);
}
//=================================================
//Privatekey file reading
File file6 = SPIFFS.open("/private.pem.key", "r");
if (!file6) {
Serial.println("Failed to open file for reading");
return;
}
Serial.println("privateKey File Content:");
while (file6.available()) {
Read_privatekey = file6.readString();
Serial.println(Read_privatekey);
}
//=====================================================
char* pRead_rootca;
pRead_rootca = (char *)malloc(sizeof(char) * (Read_rootca.length() + 1));
strcpy(pRead_rootca, Read_rootca.c_str());
char* pRead_cert;
pRead_cert = (char *)malloc(sizeof(char) * (Read_cert.length() + 1));
strcpy(pRead_cert, Read_cert.c_str());
char* pRead_privatekey;
pRead_privatekey = (char *)malloc(sizeof(char) * (Read_privatekey.length() + 1));
strcpy(pRead_privatekey, Read_privatekey.c_str());
Serial.println("================================================================================================");
Serial.println("Certificates that passing to espClient Method");
Serial.println();
Serial.println("Root CA:");
Serial.write(pRead_rootca);
Serial.println("================================================================================================");
Serial.println();
Serial.println("Cert:");
Serial.write(pRead_cert);
Serial.println("================================================================================================");
Serial.println();
Serial.println("privateKey:");
Serial.write(pRead_privatekey);
Serial.println("================================================================================================");
espClient.setCACert(pRead_rootca);
espClient.setCertificate(pRead_cert);
espClient.setPrivateKey(pRead_privatekey);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
//====================================================================================================================
WiFi.macAddress(mac);
snprintf(mac_Id, sizeof(mac_Id), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.print(mac_Id);
//=====================================================================================================================
delay(2000);
}
void loop() {
float h = 80; // Reading Temperature form DHT sensor
float t = 22.5; // Reading Humidity form DHT sensor
float tF = (t * 1.8) + 32;
if (isnan(h) || isnan(t))
{
Serial.println("Failed to read from DHT sensor!");
return;
}
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
//=============================================================================================
String macIdStr = mac_Id;
String Temprature = String(t);
String Humidity = String(h);
snprintf (msg, BUFFER_LEN, "{\"mac_Id\" : \"%s\", \"Temprature\" : %s, \"Humidity\" : \"%s\"}", macIdStr.c_str(), Temprature.c_str(), Humidity.c_str());
Serial.print("Publish message: ");
Serial.print(count);
Serial.println(msg);
client.publish("temp/", msg);
count = count + 1;
//================================================================================================
}
digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}```
I recently bought an ELEGO Mega 2560, or in other words an Arduino Mega. I bought a bmp180 sensor as well. I connected the bmp in this fashion, VCC - 3.3v, GND - GND, SCL - 21, SDA - 20. I uploaded a simple code which just displayes altitude. When I go to the Serial Monitor to view the results, nothing pops up. It is suppose to say BMP init success if it connects, and fail if it doesn't. When I go to the monitor, it just doens't say anything. When I disconnect the sensor, it says fail. It appears as if the Serial Monitor just freezes. Also a headsup, my code is very messy, I'm sorry if it's hard to keep up.
#include <Wire.h>
#include <SFE_BMP180.h>
SFE_BMP180 bmp180;
float Po = 1014.9;
#define ledPin 7
#define TransmitPin 5
//int Altitude = 5;
int sendValue;
String incomingString;
unsigned long lastTransmission;
const int interval = 1000;
void setup() {
Wire.begin();
pinMode(ledPin, OUTPUT);
pinMode(2, INPUT);
pinMode(10, OUTPUT);
pinMode(TransmitPin, OUTPUT);
bool success = bmp180.begin();
Serial.begin(115200);
if (success) {
Serial.println("BMP180 init success");
}
else
Serial.println("fail");
}
void loop() {
sendValue = digitalRead(29);
if (sendValue == HIGH) {
if (millis() > lastTransmission + interval) {
Serial.println("AT+SEND=1,8,Return");
digitalWrite(TransmitPin, HIGH);
delay(100);
digitalWrite(TransmitPin, LOW);
lastTransmission = millis();
}
}
if (Serial.available()) {
incomingString = Serial.readString();
if (incomingString.indexOf("Testing!") > 0) {
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
}
}
char status;
double T, P, alt;
bool success = false;
status = bmp180.startTemperature();
if (status != 0) {
delay(1000);
status = bmp180.getTemperature(T);
if (status != 0) {
status = bmp180.startPressure(3);
if (status != 0) {
delay(status);
status = bmp180.getPressure(P, T);
if (status != 0) {
if (millis() > lastTransmission + interval) {
alt = bmp180.altitude(P, Po);
Serial.print("AT+SEND=1,8,");
int altAsFoot = alt * 3.281;
Serial.println(altAsFoot);
digitalWrite(TransmitPin, HIGH);
delay(100);
digitalWrite(TransmitPin, LOW);
}
for (int i = 0; i < 1800; i++) {
delay(1);
if (Serial.available()) {
incomingString = Serial.readString();
if (incomingString.indexOf("+OK") > 0) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
}
if (incomingString.indexOf("Testing!") > 0) {
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
}
}
}
}
}
}
}
}
Turns out it was a hardware issue. I had ground shorted to SDA. I'm assuming the same will happen if it's shorted to SCL. Make sure both SDA and SCL aren't shorted to each other or ground.
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();
}