Me and and a friend of mine are building a robot which contains a gps for arduino. We built the following circuit, to test the gps:
We're trying the following code to test the gps:
#include <SoftwareSerial.h>
#include <TinyGPS.h>
long lat,lon; // create variable for latitude and longitude object
SoftwareSerial gpsSerial(2, 3); // create gps sensor connection
TinyGPS gps; // create gps object
void setup(){
Serial.begin(9600); // connect serial
gpsSerial.begin(4800); // connect gps sensor
}
void loop(){
Serial.print("test"); //I implemented this test
while(gpsSerial.available()){ // check for gps data
Serial.print("test2"); //I implemented this test
if(gps.encode(gpsSerial.read())){ // encode gps data
Serial.print("test3"); //I implemented this test
gps.get_position(&lat,&lon); // get latitude and longitude
// display position
Serial.print("Position: ");
Serial.print("lat: ");Serial.print(lat);Serial.print(" ");// print latitude
Serial.print("lon: ");Serial.println(lon); // print longitude
}
}
}
The thing is that the serial monitor does output test number 1, but doesn't output test number 2 and number 3. So we expected the circuit we built to fail. But we double checked the wires etc. Does anybody know what the problem could be?
Any inspiration/help is welcome,
Thanks,
Justin van Til
Try this code.
#include <SoftwareSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
static void print_long(long val, long invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
SoftwareSerial ss(3,4);
void setup()
{
Serial.begin(9600);
ss.begin(9600);
}
void loop()
{
long lat, lon;
int alt;
unsigned short sentences = 0, failed = 0;
gps.get_position(&lat, &lon);
alt=gps.altitude();
Serial.print("CURRENT LATITUDE & LONGITUDE:");
Serial.print(lat);
Serial.print(",");
Serial.println(lon);
Serial.print("CURRENT ALTITUDE:");
Serial.println(alt);
smartdelay(1000);
}
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void print_long (long val, long invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len)
{
char sz[32];
if (val == invalid)
strcpy(sz, "*******");
else
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartdelay(0);
}
static void print_str(const char *str, int len)
{
int slen = strlen(str);
for (int i=0; i<len; ++i)
Serial.print(i<slen ? str[i] : ' ');
smartdelay(0);
}
Related
Summarize The Problem
I'm building an operating system using C++ on Linux Mint in Parallels Desktop Mac.
I just added keyboard support except there was a problem...
When I press one key on the keyboard, it will create around 5 or more characters. This is an image of the problem:
Describe What you've tried
All of the sources were talking about Linux kernel so I couldn't find anything. I didn't try anything.
Show some code
print.h
#ifndef PRINT_H
#define PRINT_H
#include "types.h"
#include "colours.h"
class print {
public:
void printf(char *str);
void printf(int num);
void itoa(int num, char *number);
uint32_t digit_count(int num);
uint32_t strlen(const char *str);
void print_char(char ch);
void newLine();
void init_vga(uint8_t fore_color, uint8_t back_color);
void clear_vga_buffer(uint16_t **buffer, uint8_t fore_color, uint8_t back_color);
uint16_t vga_entry(unsigned char ch, uint8_t fore_color, uint8_t back_color);
void setTextColors(uint8_t foreColor, uint8_t back_color);
print *getPrinter();
void setPrinter(print *printer1);
private:
print *ksafdkjlasdlfk;
//index for video buffer array
uint32_t vga_index;
//counter to store new lines
uint32_t next_line_index = 1;
//fore & back color values
uint8_t g_fore_color = WHITE, g_back_color = BLUE;
//digit ascii code for printing integers
int digit_ascii_codes[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
#define VGA_ADDRESS 0xB8000
#define BUFSIZE 2200
uint16_t *vga_buffer;
#define NULL 0
};
#endif
print.cpp
#include "print.h"
void print::printf(char *str) {
uint32_t index = 0;
while (str[index]) {
print_char(str[index]);
index++;
}
}
void print::printf(int num) {
char str_num[digit_count(num) + 1];
itoa(num, str_num);
printf(str_num);
}
void print::itoa(int num, char *number) {
int dgcount = digit_count(num);
int index = dgcount - 1;
char x;
if (num == 0 && dgcount == 1) {
number[0] = '0';
number[1] = '\0';
} else {
while (num != 0) {
x = num % 10;
number[index] = x + '0';
index--;
num = num / 10;
}
number[dgcount] = '\0';
}
}
uint32_t print::digit_count(int num) {
uint32_t count = 0;
if (num == 0)
return 1;
while (num > 0) {
count++;
num = num / 10;
}
return count;
}
uint32_t print::strlen(const char *str) {
uint32_t length = 0;
while (str[length])
length++;
return length;
}
void print::print_char(char ch) {
vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
vga_index++;
}
void print::newLine() {
if (next_line_index >= 55) {
next_line_index = 0;
clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
}
vga_index = 80 * next_line_index;
next_line_index++;
}
void print::init_vga(uint8_t fore_color, uint8_t back_color) {
vga_buffer = (uint16_t *) VGA_ADDRESS;
clear_vga_buffer(&vga_buffer, fore_color, back_color);
g_fore_color = fore_color;
g_back_color = back_color;
}
void print::clear_vga_buffer(uint16_t **buffer, uint8_t fore_color, uint8_t back_color) {
uint32_t i;
for (i = 0; i < BUFSIZE; i++) {
(*buffer)[i] = vga_entry(NULL, fore_color, back_color);
}
next_line_index = 1;
vga_index = 0;
}
uint16_t print::vga_entry(unsigned char ch, uint8_t fore_color, uint8_t back_color) {
uint16_t ax = 0;
uint8_t ah = 0, al = 0;
ah = back_color;
ah <<= 4;
ah |= fore_color;
ax = ah;
ax <<= 8;
al = ch;
ax |= al;
return ax;
}
void print::setTextColors(uint8_t foreColor, uint8_t back_color) {
g_fore_color = foreColor;
g_back_color = back_color;
}
print *print::getPrinter() {
return ksafdkjlasdlfk;
}
void print::setPrinter(print *printer1) {
ksafdkjlasdlfk = printer1;
}
keyboard.h
#ifndef APOS_KEYBOARD_H
#define APOS_KEYBOARD_H
#include "../../utils/types.h"
#include "../../utils/print.h"
#include "char.h"
class keyboard {
public:
void enableKeyboard();
void test_input();
void sleep(uint32_t timer_count);
void wait_for_io(uint32_t timer_count);
char get_input_keycode();
void outb(uint16_t port, uint8_t data);
uint8_t inb(uint16_t port);
};
#endif //APOS_KEYBOARD_H
keyboard.cpp
#include "keyboard.h"
uint8_t keyboard::inb(uint16_t port) {
uint8_t ret;
asm volatile("inb %1, %0" : "=a"(ret) : "d"(port));
return ret;
}
void keyboard::outb(uint16_t port, uint8_t data) {
asm volatile("outb %0, %1" : "=a"(data) : "d"(port));
}
char keyboard::get_input_keycode() {
char ch = 0;
while ((ch = inb(KEYBOARD_PORT)) != 0) {
if (ch > 0)
return ch;
}
return ch;
}
/*
keep the cpu busy for doing nothing(nop)
so that io port will not be processed by cpu
here timer can also be used, but lets do this in looping counter
*/
void keyboard::wait_for_io(uint32_t timer_count) {
while (1) {
asm volatile("nop");
timer_count--;
if (timer_count <= 0)
break;
}
}
void keyboard::sleep(uint32_t timer_count) {
wait_for_io(timer_count);
}
void keyboard::test_input() {
char ch = 0;
char keycode = 0;
do {
keycode = get_input_keycode();
if (keycode == KEY_ENTER) {
print printt;
printt.getPrinter()->newLine();
} else {
ch = get_ascii_char(keycode);
print printt;
printt.getPrinter()->print_char(ch);
}
sleep(0x02FFFFFF);
} while (ch > 0);
}
void keyboard::enableKeyboard() {
test_input();
}
The kernel.cpp just has the test_intput command and prints a few things.
There are a few files there, but that main ones are the kernel.cpp, hardware/keyboard/all the files there.
Either use a seperate Thread to handle the input reckognition function, that way you can use a sleep without blocking the main Thread. You could also save the current pressed key and save it as a previous key and check if it has changed, if not the button has not been released yet. so you can avoid multiples.
I'm working on a function to display static map on TFT display (I use ESP32.). The map link is as follows (a http link):
http://osm-static-maps.herokuapp.com/?geojson=[{%22type%22:%22Point%22,%22coordinates%22:[32.37956,51.66127]}]&height=400&width=600&zoom=13&type=jpeg
and my code is as follows:
#define WIFI_SSID "<your SSID>"
#define PASSWORD "<your password>"
#define LINK "http://osm-static-maps.herokuapp.com/?geojson=[{%22type%22:%22Point%22,%22coordinates%22:[32.37956,51.66127]}]&height=400&width=600&zoom=13&type=jpeg"
#include <TJpg_Decoder.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#define BUFSIZE 40000
uint8_t* jpgbuffer;
unsigned long jp = 0;
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) {
if ( y >= tft.height() ) return 0;
tft.pushImage(x, y, w, h, bitmap);
return 1;
}
void setup() {
jpgbuffer = (uint8_t *) malloc (BUFSIZE);
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
TJpgDec.setJpgScale(1);
TJpgDec.setSwapBytes(true);
TJpgDec.setCallback(tft_output);
WiFi.begin(WIFI_SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println();
uint32_t t = millis();
bool loaded_ok = downFile(LINK, jpgbuffer);
t = millis() - t;
if (loaded_ok) {
Serial.print("Downloaded in "); Serial.print(t); Serial.println(" ms.");
}
t = millis();
TJpgDec.drawJpg(0, 0, jpgbuffer, jp);
t = millis() - t;
Serial.print("Decoding and rendering: "); Serial.print(t); Serial.println(" ms.");
}
void loop() {
}
bool downFile(String url, uint8_t* jpgbuffer) {
Serial.println("Downloading file from " + url);
if ((WiFi.status() == WL_CONNECTED)) {
HTTPClient http;
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
int total = http.getSize();
int len = total;
uint8_t buff[128] = { 0 };
WiFiClient * stream = http.getStreamPtr();
while (http.connected() && (len > 0 || len == -1)) {
size_t size = stream->available();
if (size) {
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
memcpy (jpgbuffer + jp, buff, c);
jp = jp + c;
if (len > 0) {
len -= c;
}
}
yield();
}
Serial.println();
Serial.print("[HTTP] connection closed or file end.\n");
}
}
else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
return 1;
}
Everything is OK when I use the link below, for example:
#define LINK "http://dellascolto.com/lorenz.jpg"
But when I use the link below, the Arduino hangs after uploading the code!
#define LINK "http://osm-static-maps.herokuapp.com/?geojson=[{%22type%22:%22Point%22,%22coordinates%22:[32.37956,51.66127]}]&height=400&width=600&zoom=13&type=jpeg"
Apparently, when JSON part is removed from the map link, the program runs correctly. How to solve the problem.
The image doesn't fit your buffer. It is 78886 bytes strong. You only allocate 40000 bytes.
Postpone allocation until you know the size:
total = http.getSize();
*jpgbuffer = malloc(total);
Note that in order to do so you meed pass jpgbuffer as uint8_t **.
I'm trying to program a class to control the MPU6050 with the Arduino Wire library but when I run the code in my Arduino mini it freezes after a few seconds.
There is the code of the library and a test sketch:
// Include Wire Library for I2C
#include <Wire.h>
enum MPU6050_filter {_256Hz, _188Hz, _98Hz, _42Hz, _20Hz, _10Hz, _5Hz};
enum MPU6050_gyro {_250dps, _500dps, _1000dps, _2000dps};
enum MPU6050_accel {_2g, _4g, _8g, _16Hz};
class MPU6050
{
public:
MPU6050 ();
bool start (bool AD0_value);
void goToSleep ();
void stopSleeping ();
void setFilterVal (MPU6050_filter filter_val);
void setGyroRange (MPU6050_gyro range);
void setAccelRange (MPU6050_accel range);
bool dataAvailable ();
void getLastGyroData (float& gx, float& gy, float& gz);
void getRawGyroData (int& gx, int& gy, int& gz);
private:
void writeRegister (byte address, byte data);
byte readRegister (byte address);
void readData (byte start_address, byte bytes, byte* data);
float convertGyroToDPS (int gyro);
bool AD0_val;
MPU6050_filter filter;
MPU6050_accel accel_range;
MPU6050_gyro gyro_range;
unsigned long last_read;
const unsigned long min_read_time = 1;
};
MPU6050::MPU6050 () : AD0_val(false),
filter(_256Hz),
accel_range(_2g),
gyro_range(_250dps) {}
bool MPU6050::start (bool AD0_value)
{
AD0_val = AD0_value;
// init sample rate div to 0 (max sample rate)
writeRegister(0x19, 0);
// activate FIFO for gyroscope data
writeRegister(0x23, 0x70);
// clear config setup register
writeRegister(0x6B, 0);
// setup the register
writeRegister(0x37, 0x10);
// set interrupt by data ready
writeRegister(0x38, 0x01);
}
void MPU6050::goToSleep ()
{
byte prev_data = readRegister(0x6B);
prev_data = (prev_data | 0x40);
writeRegister(0x6B, prev_data);
}
void MPU6050::stopSleeping ()
{
byte prev_data = readRegister(0x6B);
prev_data = (prev_data & 0xBF);
writeRegister(0x6B, prev_data);
}
void MPU6050::setFilterVal (MPU6050_filter filter_val)
{
int val;
if (filter_val == _256Hz) val = 0;
else if (filter_val == _188Hz) val = 1;
else if (filter_val == _98Hz) val = 2;
else if (filter_val == _42Hz) val = 3;
else if (filter_val == _20Hz) val = 4;
else if (filter_val == _10Hz) val = 5;
else val = 6;
byte data = readRegister(0x1A);
data = (data & 0xF8) | (val & 0x07);
writeRegister(0x1A, data);
filter = filter_val;
}
void MPU6050::setAccelRange (MPU6050_accel range)
{
byte value;
if (range == _2g) value = 0;
else if (range == _4g) value = 1;
else if (range == _8g) value = 2;
else value = 3;
byte reg_value = readRegister(0x1C);
reg_value = (reg_value & 0xE0) | (value << 3);
writeRegister(0x1C, reg_value);
accel_range = range;
}
void MPU6050::setGyroRange (MPU6050_gyro range)
{
byte value;
if (range == _250dps) value = 0;
else if (range == _500dps) value = 1;
else if (range == _1000dps) value = 2;
else value = 3;
byte reg_value = readRegister(0x1B);
reg_value = (reg_value & 0xE0) | (value << 3);
writeRegister(0x1B, reg_value);
gyro_range = range;
}
bool MPU6050::dataAvailable ()
{
return (readRegister(0x3A) & 0x01);
}
void MPU6050::getLastGyroData (float& gx, float& gy, float& gz)
{
int raw_x, raw_y, raw_z;
getRawGyroData(raw_x, raw_y, raw_z);
gx = convertGyroToDPS(raw_x);
gy = convertGyroToDPS(raw_y);
gz = convertGyroToDPS(raw_z);
}
void MPU6050::getRawGyroData (int& gx, int& gy, int& gz)
{
byte* data = new byte[6];
readData(0x43, 6, data);
gx = data[0] << 8 | data[1];
gy = data[2] << 8 | data[3];
gz = data[4] << 8 | data[5];
delete data;
}
void MPU6050::writeRegister (byte address, byte data)
{
Wire.beginTransmission(0x68 + AD0_val);
Wire.write(address);
Wire.write(data);
Wire.endTransmission();
}
byte MPU6050::readRegister (byte address)
{
byte data_buff = 0x00;
Wire.beginTransmission(byte(0x68 + AD0_val));
//Send the requested starting register
Wire.write(address);
//End the transmission
Wire.endTransmission(false);
//Request 14 bytes from the MPU-6050
Wire.requestFrom(byte(0x68 + AD0_val), byte(0x01), byte(true));
unsigned long initial_time = millis();
//Wait until all the bytes are received
while(Wire.available() == 0 and millis() < initial_time + 5);
if (millis() < initial_time + 5)
{
// read the data
data_buff = Wire.read();
}
// end the transmission
Wire.endTransmission();
return data_buff;
}
void MPU6050::readData (byte start_address, byte bytes, byte* data)
{
Wire.beginTransmission(byte(0x68 + AD0_val));
//Send the requested starting register
Wire.write(start_address);
//End the transmission
Wire.endTransmission(false);
//Request 14 bytes from the MPU-6050
Wire.requestFrom(byte(0x68 + AD0_val), bytes, byte(true));
//Wait until all the bytes are received
while(Wire.available() < bytes);
for (int i = 0; i < bytes; i++)
data[i] = Wire.read();
Wire.endTransmission();
}
float MPU6050::convertGyroToDPS (int gyro)
{
if (gyro_range == _250dps) return float(gyro)/131.0;
else if (gyro_range == _500dps) return float(gyro)/65.5;
else if (gyro_range == _1000dps) return float(gyro)/32.8;
else return float(gyro)/16.4;
}
#define SHOW_EACH 50
MPU6050 chip;
unsigned long last_shown = 0;
unsigned this_fps = 0;
unsigned last_fps = 0;
unsigned last_time = 0;
unsigned total_fps = 0;
float g_x, g_y, g_z;
void setup()
{
Serial.begin(115200);
Serial.println("--------");
chip.setFilterVal(_256Hz);
chip.setGyroRange(_250dps);
chip.start(false);
}
void loop()
{
if (chip.dataAvailable())
chip.getLastGyroData(g_x, g_y, g_z);
++this_fps;
++total_fps;
if (millis()/1000 != last_time)
{
last_time = millis()/1000;
last_fps = this_fps;
this_fps = 0;
}
if (millis() - last_shown >= SHOW_EACH)
{
last_shown = millis();
Serial.print(g_x);
Serial.print(" ");
Serial.print(g_y);
Serial.print(" ");
Serial.print(g_y);
Serial.print(" ");
Serial.print(last_fps);
Serial.print(" ");
Serial.println(total_fps);
}
}
Some testing with Serial.println points to the function requestFrom from the Wire library. What can be the cause?
Sorry that i write this as an answer, but I can't write comments yet.
1st. There are multiple requestFrom() calls in your code, so it would be better to specify where does the problem occure exactly (if you can).
2nd. Are you completely sure that, it's the requestFrom() where your code hang. In readData() there is a while() just after requestFrom(). Maybe it hangs there, as the other device don't send enough bytes (for some reasons).
Anyway this might help a litle (link), here they recommend to always check the return value of endTransmission().
I am struggling with a CAN code. with Arduino I am sending two signals with 2 different identifiers and my code checks the identifier id and then interprets the message as eithr state-of-charge or a Voltage message. The code works fine with a single SOC or volt message.
The problem im getting is that when there are multiple message, the code reads the identifier once and then reads all messages given. This means, it reads id 0x140, then reads all signals even the ones that are associated with other ids.
I don't know if its problem with my code or have to activate some flags or something.
//WORKS FINE FOR A SINGLE CAN MESSAGE, BUT HAVE ID - MESSAGE SYN ISSUES
//WITH MULTIPLE MESSAGES//
#include "pin_info.h"
#include <stdio.h>
#include <stdlib.h>
#include <Time.h>
#include <SPI.h> //for CAN
#include "mcp_can.h"
//#include "canLib.h"
#include "FreeMono9pt7b.h"
const int spiCSPin = 3;
MCP_CAN CAN(spiCSPin);
unsigned char len = 0;
unsigned char temp_buf[8];
unsigned char soc_buf[8]={0};
unsigned char volt_buf[8]={0};
unsigned char soc_mean[2], soc_min[2], soc_max[2] ={0,0};
float s_mean, s_min, s_max;
unsigned char volt_mean[2], volt_max[2], volt_min[2]= {0,0};
float v_mean, v_min, v_max;
int len_= sizeof(soc_mean);
const char Message[]= "CAN Message: " ;
const char Name[]= "foxBMS";
//enum type{soc,SOC, volt, VOLT};
void setup()
{
/*FOR CAN*/
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);
while (CAN_OK != CAN.begin(CAN_500KBPS))
{
Serial.println("CAN BUS Init Failed");
delay(100);
}
Serial.println("CAN BUS Init OK!");
/* set mask, set both the mask to 0x3ff*/
CAN.init_Mask(0, 0, 0x3ff); // there are 2 mask in mcp2515, you need to set both of them
CAN.init_Mask(1, 0, 0x3ff);
/*set filter, we can receive id from 0x140 & 0x170 */
CAN.init_Filt(0, 0, 0x140); // there are 6 filter in mcp2515
CAN.init_Filt(1, 0, 0x170); // there are 6 filter in mcp2515
}
void loop()
{
if(CAN_MSGAVAIL == CAN.checkReceive())
{
unsigned long canId = CAN.getCanId();
CAN.readMsgBuf(&len, temp_buf);
assign(temp_buf,canId);
serialDisplay(canId);
//CAN.checkClearRxStatus(temp_buf);
CAN.clearBufferTransmitIfFlags();
}
else
{ Serial.print("No message received \n");
}
}
void assign(unsigned char buf[], unsigned long id)
{
if(id==0x00)
{}
else if(id==0x140)
{
for (int i=0; i<len; i++)
{
if (i<2)
soc_mean[i]= buf[i];
else if (i<4 && i>=2)
soc_min[i-2]= buf[i];
else if (i<6 && i>=4)
soc_max[i-4]= buf[i];
}
}
else if(id==0x170)
{
for (int i=0; i<len; i++)
{
if (i<2)
volt_mean[i]= buf[i];
else if (i<4 && i>=2)
volt_min[i-2]= buf[i];
else if (i<6 && i>=4)
volt_max[i-4]= buf[i];
}
}
}
void serialDisplay(unsigned long id)
{
Serial.println("-----------------------------");
Serial.print("Data from ID: ");
Serial.print(id,HEX); Serial.println("- CAN0_MSG");
for(int i = 0; i<len; i++)
{
Serial.print(temp_buf[i], HEX); Serial.print("\t");
}
Serial.print("\n");
}
I'm fiddling with an Arduino project where I've got these structs in my main file:
struct gpsCoord_t {
long latitude;
long longitude;
};
struct track_t {
char code[4];
gpsCoord_t bounds[4];
gpsCoord_t points[4];
};
Next to that I've got a function to dump variables of this type to the serial bus in that same file:
void dumpTrack(track_t track) {
Serial.print("\nTrack: ");
Serial.print(track.code);
Serial.print("\nTrack bounds: ");
Serial.print("\n- 1 lat: ");
Serial.print(track.bounds[0].latitude);
Serial.print("\n- 1 lon: ");
Serial.print(track.bounds[0].longitude);
}
The compiler produces 2 errors without line numbers from which I believe the first one is caused by the second one:
error: variable or field 'dumpTrack' declared void
error: 'track_t' was not declared in this scope
EDIT here's the complete file:
#include <Wire.h> //I2C library
#include <I2C_eeprom.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
I2C_eeprom ee(0x50);
const int baseTrackAddress = 3;
const int trackSize = 68;
const int maxTracks = 480;
int powerOnLED = 2;
int gpsFixLED = 3;
int trackFoundLED = 4;
int errorLED = 6;
int gpsSensor = 7;
TinyGPS gps;
SoftwareSerial nss(gpsSensor, 255);
int calcTrackAddress(int trackId) {
return (trackId*trackSize) + baseTrackAddress;
}
struct gpsCoord_t {
long latitude;
long longitude;
};
struct track_t {
char code[4];
gpsCoord_t bounds[4];
gpsCoord_t points[4];
};
track_t tracks[maxTracks];
void setup()
{
Serial.begin(115200);
Serial.flush();
Serial.print("Demo I2C eeprom library ");
Serial.print(I2C_EEPROM_VERSION);
Serial.println("\n");
strcpy(tracks[0].code, "X11");
tracks[0].bounds[0].latitude = 0;
tracks[0].bounds[0].longitude = 0;
tracks[0].points[0].latitude = 0;
tracks[0].points[0].longitude = 0;
ee.writeBlock(3, (uint8_t*)&tracks[0], trackSize);
}
void loop()
{
Serial.println("\nTEST: 64 byte page boundary writeBlock");
dumpEEPROM(0, 255);
while(1);
}
void dumpTrack(track_t track) {
Serial.print("\nTrack: ");
Serial.print(track.code);
Serial.print("\nTrack bounds: ");
Serial.print("\n- 1 lat: ");
Serial.print(track.bounds[0].latitude);
Serial.print("\n- 1 lon: ");
Serial.print(track.bounds[0].longitude);
}
void readTrack(int trackId) {
track_t track;
ee.readBlock(60, (uint8_t*)&track, 10);
}
void readTracks() {
}
void dumpEEPROM(unsigned int addr, unsigned int length)
{
// block to 10
addr = addr / 10 * 10;
length = (length + 9)/10 * 10;
byte b = ee.readByte(addr);
for (int i = 0; i < length; i++)
{
if (addr % 10 == 0)
{
Serial.println();
Serial.print(addr);
Serial.print(":\t");
}
Serial.print(b);
b = ee.readByte(++addr);
Serial.print(" ");
}
Serial.println();
}
void ProcessCommand(char* command) {
//switch(*command==)
}
char* ReadSerialCommand() {
int i=0;
char commandbuffer[100];
if(Serial.available()){
delay(100);
while( Serial.available() && i< 99) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
}
if(i>0)
return (char*)commandbuffer;
else
return 0L;
}
When I put the entire dumpTrack function in comment, the errors go away. I've checked a couple of times for a typo but failed to find any.
It seems you are compiling this code as C.
Instead of
struct track_t {
char code[4];
gpsCoord_t bounds[4];
gpsCoord_t points[4];
};
write
typedef struct {
char code[4];
gpsCoord_t bounds[4];
gpsCoord_t points[4];
} track_t;
I suspect somewhere in a header there is a variable called dumpTrack. Why don't you just rename the function to something else?
Also in general it is good to avoid using reserved words as function names; "loop" is not a good choice for a function name.
Edit: the latter is probably the reason for your problem.