Hi, I’m working with my nephew to connect his go-kart to the internet. Fun project!
Here are config details:
Arduino Mega v3
Winc1500 wifi breakout board (which connects to a mobile phone hotspot)
Dexter GPS shield - for speed and location
Temp sensor for engine oil temp.
The solution is powered by a 12v battery that is plugged into the power jack of the Arduino Mega. (Most of my testing is done with AC power though)
So, GPS is powered via pins on shield
wifi is powered via other open 5v pins on Mega
temp sensor takes power from breadboard fed from mega.
All data is being published to the dashboard at adafruit.io, which relies on mqtt for the data transfer protocol from the client device to the cloud.
This Dexter GPS and accompanying libraries are awesome! The GPS works great using Dexter provided sample code. However, once integrated into the larger code base for this project, we have a GPS issue: The call to dgps.update() does not return data. I get an accurate initial reading of velocity based on initialization of the GPS but that value never changes thereafter. But, this works fine on the same board if I’m just running GPS sample code alone. (My current code is just using dummy values for lat long until I get the update issue figured out)
dgps.update() is being called in loop() while the wifi is running and wifi is pushing data to mqtt / adafruit. Possibly this is some timing issues or power issue?
Am I calling dgps.Update correctly? My call is as follows: dgps.update(Maple_Valley[0],Maple_Valley[1]). This call works when I use it in the Dexter sample but does not work in the context of my code pasted below.
I’ve been stumped on this for days. I’ve also tried different GPSs which exhibit similar behavior, which makes me think it is my board setup or code.
I was hoping to have this issue figured out days ago. My nephew and I are supposed to wrap this up this weekend (for an upcoming school project deadline) and I am at my wits end !
Here is the entire code in the sketch if that helps.
I would GREATLY appreciate any sage advice from anyone on the forum!
Thanks in advance (and thanks for a cool product Dexter)!
Jonathan
#include “allheaders.h” //GPS and other headers all go in this file
#include “config.h”
/************************* WiFI Setup *****************************/
//alt mega config
#define WINC_CS 17
#define WINC_IRQ 15 //moved from 18…put GPS on 18 and 19
#define WINC_RST 20 //moved from 19
//#define WINC_CS 8
//#define WINC_IRQ 7
//#define WINC_RST 4
//#define WINC_EN 2 // EN tied directly to 5v. Put it on 2 to control it from arduino, which we don’t need
Adafruit_WINC1500 WiFi(WINC_CS, WINC_IRQ, WINC_RST);
int status = WL_IDLE_STATUS;
/************ Global State (you don’t need to change this!) ******************/
//Set up the wifi client
Adafruit_WINC1500Client client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
// define halt
#define halt(s) { Serial.println(F( s )); while(1); }
/****************************** Feeds ***************************************/
Adafruit_MQTT_Publish temp = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME “/feeds/temp”);
Adafruit_MQTT_Publish vel = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME “/feeds/vel”);
Adafruit_MQTT_Publish loc = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME “/feeds/loc”);
// ‘onoff’ feed for subscribing to changes.
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME “/feeds/onoff”);
/Temp Sensor setup******/
int DS18S20_Pin = 39; //DS18S20 Signal pin
OneWire ds(DS18S20_Pin);
/*************GPS Pins and default location config *****************************/
// Software serial TX & RX Pins for the GPS module
// Initiate the software serial connection
int ledPin = 13; // LED test pin
dGPS dgps = dGPS(); // Construct dGPS class
float Maple_Valley[]={47.42402, -122.0279}; //need a location to for gps “update” command
/*************************** Sketch Code ************************************/
//#define LEDPIN 13 //try without this
void setup() {
#ifdef WINC_EN
pinMode(WINC_EN, OUTPUT);
digitalWrite(WINC_EN, HIGH);
#endif
//setup LEDs
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
SetState(0);
while (!Serial);
Serial.begin(115200);
Serial.println(F(“Connect Go Kart To the Cloud”));
Serial.println("");
// Initialise the Client
Serial.print(F("\nStart WiFi …"));
SetState(1); //light LED
// check for the presence of the breakout
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println(“WINC1500 wifi device not present”);
// don’t continue:
while (true);
}
Serial.println(“Wifi started!”);
//pinMode(LEDPIN, OUTPUT); /try without this
mqtt.subscribe(&onoffbutton);
//gps pin
pinMode(ledPin, OUTPUT); // Initialize LED pin. Do I really need this?
//Initialize GPS
SetState(2); //light LED
Serial.println(“Starting GPS.”);
dgps.init(); // Initialize dGPS.
delay(1000);
Serial.println(“GPS started!”);
}
void loop() {
// Reset watchdog every loop
Watchdog.reset();
//Reset LED state
SetState(0);
//Connect / reconnect to mqtt if needed. see function def below
MQTT_connect();
// this is our ‘wait for incoming subscription packets’ busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if (subscription == &onoffbutton) {
Serial.print(F("Got: "));
Serial.println((char *)onoffbutton.lastread);
if (0 == strcmp((char *)onoffbutton.lastread, "OFF")) {
digitalWrite(buzzerPin, LOW);
}
if (0 == strcmp((char *)onoffbutton.lastread, "ON")) {
digitalWrite(buzzerPin, HIGH);
}
}
}
//set temp
float temperatureC = getTemp(); //will take about 750ms to run. there is a delay() call in getTemp()
float temperatureF = temperatureC*1.8 + 32;
//set speed
dgps.update(Maple_Valley[0],Maple_Valley[1]); //call update for any location
float veldata = dgps.Vel();
Serial.println(“Speed.”);
Serial.println(veldata);
//set location - update this with real code
char locdata[] = “1, -47.42, -122.03, 1”; //for location
// Now we can publish stuff!
SetState(3);
Serial.print(F("\nSending temperature value “));
Serial.print(temperatureF);
Serial.print(”…");
if (! temp.publish(temperatureF)) {
Serial.println(F(“Failed”));
} else {
Serial.println(F(“OK!”));
}
Serial.print(F("\nSending speed/velocity “));
Serial.print(veldata);
Serial.print(”…");
if (! vel.publish(veldata)) {
Serial.println(F(“Failed”));
} else {
Serial.println(F(“OK!”));
}
Serial.print(F("\nSending location “));
Serial.print(locdata);
Serial.print(”…");
if (! loc.publish(locdata)) {
Serial.println(F(“Failed”));
} else {
Serial.println(F(“OK!”));
}
SetState(4); //light final LED, showing last data point in loop has been sent
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// attempt to connect to Wifi network:
while (WiFi.status() != WL_CONNECTED) {
Serial.print("Connect wifi to: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
uint8_t timeout = 10;
while (timeout && (WiFi.status() != WL_CONNECTED)) {
timeout--;
delay(1000);
}
}
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connect to Adafruit.io … ");
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println(“Retrying adafruit.io connection in 5 seconds…”);
mqtt.disconnect();
delay(5000); // wait 5 seconds
}
Serial.println(“Connected!”);
}
float getTemp(){
//returns the temperature from one DS18S20 in DEG Celsius
byte data[12];
byte addr[8];
if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println(“CRC is not valid!”);
return -1000;
}
if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print(“Device is not recognized”);
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(750); // Wait for temperature conversion to complete
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (int i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << 8) | LSB); //using two’s compliment
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
//function for controlling LEDs
void SetState(int state){
switch(state){
//note power LED is lit directly from bboard
case 0: //wifi connected
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
break;
case 1: //wifi connected
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
break;
case 2: //adafruit connected
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
break;
case 3: //gps initialized
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, LOW);
break;
case 4: //data published
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, HIGH);
break;
}
}