#include <iarduino_OLED.h>
#include <SoftwareSerial.h>
#include <MsTimer2.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
//
SoftwareSerial ss(RXPin, TXPin);
iarduino_OLED myOLED(0x3C); // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x3C или 0x3D.
extern uint8_t MediumFontRus[]; // Подключаем шрифт MediumFontRus.
extern uint8_t SmallFontRus[];
extern uint8_t BigNumbers[];
int flag=0;
int flag1=0;
int flag2=0;
byte n;
byte regim=1;
byte speed1;
float gps_speed;
void flash() {
static boolean output = HIGH;
digitalWrite(7, output);
output = !output;
}
void setup(void) {
MsTimer2::set(150, flash); // 500ms period
MsTimer2::start();
Serial.begin(57600);
ss.begin(GPSBaud);
myOLED.begin();
delay(200);
pinMode(7, OUTPUT);
pinMode(9,OUTPUT);
digitalWrite(9,HIGH );
delay(200);
myOLED.begin();
myOLED.setFont(MediumFontRus); // Указываем шрифт который требуется использовать для вывода цифр и текста.
myOLED.print(F("УРАГАН-13"), 8,24);
myOLED.print(F("Клеменчев"), 8,60);
delay(2000);
myOLED.clrScr();
//myOLED.print(("ГОРОД"), 5,14);
myOLED.setCursor(80,55);
myOLED.setFont(MediumFontRus);
myOLED.print("КМ/Ч");
myOLED.autoUpdate(false);
}
//
// Эта функция принимает символ из Serial и возвращает
// указатель на полученную строку или NULL, если строка
// ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
//
static const int MAX_LEN = 120; // 120 - максимальная длина строки - надо посмотреть правильное значение в описании протокола!
char * getStrFromSerial(void) {
static bool waitingForStrBegin = true; // истина, если мы ждём начала строки ($)
static char strBuf[MAX_LEN]; // буфер для строки
static int ptr = 0; // индекс свободного байта в буфере
//
// Если буфер переполнился, печатаем сообщение и начинаем ждать новую строку
//
if (ptr >= MAX_LEN) {
Serial.println("*** Error: Too long string!!!");
ptr = 0;
waitingForStrBegin = true;
return NULL;
}
//
// Если в Serial ничего нет - выходим
// А если есть, то читаем 1 символ
//
if (!ss.available()) return NULL;
const char c = ss.read();
Serial.print(c);
//
// Если мы ждём начала строки, то сравинваем
// прочитанный символ с '$', если равен - начало найдено
//
if (waitingForStrBegin) {
if (c == '$') {
ptr = 0;
strBuf[ptr++] = c;
waitingForStrBegin = false;
}
return NULL;
}
//
// Если прочитанный символ - перевод строки или возврат каретки
// то считаем, что строка закончилась. Возвращаем её,
// а сами готовимся ждать новую.
//
if (c == '\r' || c == '\n') {
strBuf[ptr] = '\0';
waitingForStrBegin = true;
return strBuf;
}
//
// Просто записываем символ в строку
//
strBuf[ptr++] = c;
return NULL;
}
//
// Читаeм долготу и широту, складывает в lon и lat
// Возвращает true, если прочитала и false если нет
//
bool readLatLon(double & time,double & latitude, double & speed )
{
// getStrFromSerial() вернёт строку, полученную из Serial
// или NULL, если строка ещё пока не получена
//
const char * str = getStrFromSerial();
//
// Если строка ещё не получена, выходим
//
if (str == NULL) return false;
//
// Если строка не начинается с "$GPGGA или GPRMC",
// то она нам не нужна выходим
//
;
const char * prefix = "$GPRMC";
//
//
if ( ! strncmp(str, prefix, strlen(prefix)))
{
char * comma = strchr(str, ',');
//
// Если не нашли (строка кривая пришла?) - выходим
//
if (!comma) return false;
//
// со следующего символа просле запятой идёт числоа - широта
//
time = atof(comma+1);
//
// Ищем вторую запятую после начала числа-широты
//
comma = strchr(comma+1, ','); // сначала ищем первую запятую 2
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 3
if (!comma) return false; // почему-то не нашли :((((
latitude=atof(comma+1);
comma = strchr(comma+1, ','); // сначала ищем первую запятую 4
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 5
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // сначала ищем первую запятую 6
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 7
if (!comma) return false; // почему-то не нашли :((((
speed=atof(comma+1)*1.852; // переводим скорость в км/час
//speed=atof(comma+1);
return true;
}
}
void loop() {
//myOLED.setFont(BigNumbers);
//myOLED.print(speed,30,55,0);
//myOLED.print(gps_speed,30,55,0);
double speed,latitude, time;
//Читаем время,кол-во спутников,,скорость если успешно прочитались, печатаем
if (readLatLon(time, latitude,speed)) {
//speed=gps_speed;
//speed--;
if (digitalRead(5)==HIGH&&flag==0) //по нажатию кнопки включается либо режим
{ // ГОРОД либо ТРАССА
regim++;
flag=1;
if (regim>2) regim=1;
}
if (digitalRead(6)==LOW&&flag==1)
{
flag=0;
}
if (regim==1)
{
myOLED.update();
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
n=1;
speed1=1;
}
if (regim==2)
{
myOLED.update();
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
n=2;
speed1=2;
}
if (digitalRead(6)==HIGH&&flag2==0 ) // по нажатию кнопки выключается либо включается OLED дисплей
{ // через полевой транзистор
flag2=1;
digitalWrite(9,!digitalRead(9));
if (n==1)
{
myOLED.begin();
myOLED.print("КМ/Ч",80,55);
regim=1;
}
if (n==2)
{
myOLED.begin();
myOLED.print("КМ/Ч",80,55);
regim=2;
}
}
if (digitalRead(6)==LOW &&flag2==1 )
{
flag2=0;
}
if (speed1==1) //если скорость более 78км/ч моргает светодиод
{ //если менее-гаснет
if (speed>=78 )
{
digitalWrite(7, !digitalRead(7));
}
else
{
digitalWrite(7,LOW);
}
}
if (speed1==2)
{
if (speed>=108) //если скорость более 108км/ч моргает светодиод
{ //если менее-гаснет
digitalWrite(7, !digitalRead(7));
}
else
{
digitalWrite(7,LOW);
}
}
if (latitude>10)
{
myOLED.setCursor(95,14);
myOLED.setFont(MediumFontRus);
myOLED.print("GPS",90,14); //выводим кол-во спутников
}
else myOLED.print("NON",90,14);
if (speed<100 && speed>10) // тут при выводе скорости, если число двухзначное
{ // закрашиваем младший разряд
//myOLED.print(" ",59,40);
//myOLED.print(" ",59,55);
}
if (speed<10)
{
myOLED.update();
//myOLED.print(" ",44,40);
//myOLED.print(" ",44,55);
}
myOLED.update();
myOLED.setFont(BigNumbers);
myOLED.print(speed,30,55,0); //выводим скорость
//myOLED.print(gps_speed,30,55,0);
Serial.println();
Serial.print("time: ");
Serial.print(time, 2);
Serial.print(" latitude: ");
Serial.print(latitude,0);
//Serial.print(" date: ");
//Serial.println(date, 0);
Serial.print(" speed: ");
Serial.print(speed, 4);
}
}
При таком коде данные выводятся как положено, через каждые 200мс. Результат прилагаю.
Но мне надо закрасить на экране при выводе скорости два правых разряда, чтобы при скорости менее 10км/ч на дисплее индицировалось однозначное число.(просто если скорость была более 10км/час то младший разряд остается на экране, вот я и затираю его пробелами). Так вот, при раскомментировании строк 276-277 получается вот такой результат.
Но мне надо закрасить на экране при выводе скорости два правых разряда, чтобы при скорости менее 10км/ч на дисплее индицировалось однозначное число.(просто если скорость была более 10км/час то младший разряд остается на экране, вот я и затираю его пробелами). Так вот, при раскомментировании строк 276-277 получается вот такой результат.
Переподключился к аппаратному порту, скорость GPS изменил уже на 9600, порт тоже настроен на 9600, результат тот же.Почему то сообщение когда время 144256,40 пропускается, а перед ним выводится не полностью.
#include <iarduino_OLED.h>
//#include <SoftwareSerial.h>
#include <MsTimer2.h>
//static const int RXPin = 4, TXPin = 3;
//static const uint32_t GPSBaud = 9600;
//
//SoftwareSerial ss(RXPin, TXPin);
iarduino_OLED myOLED(0x3C); // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x3C или 0x3D.
extern uint8_t MediumFontRus[]; // Подключаем шрифт MediumFontRus.
extern uint8_t SmallFontRus[];
extern uint8_t BigNumbers[];
int flag=0;
int flag1=0;
int flag2=0;
byte n;
byte regim=1;
byte speed1;
float gps_speed;
void flash() {
static boolean output = HIGH;
digitalWrite(7, output);
output = !output;
}
void setup(void) {
MsTimer2::set(150, flash); // 500ms period
MsTimer2::start();
Serial.begin(9600);
//ss.begin(GPSBaud);
myOLED.begin();
delay(200);
pinMode(7, OUTPUT);
pinMode(9,OUTPUT);
digitalWrite(9,HIGH );
delay(200);
myOLED.begin();
myOLED.setFont(MediumFontRus); // Указываем шрифт который требуется использовать для вывода цифр и текста.
myOLED.print(F("УРАГАН-13"), 8,24);
myOLED.print(F("Клеменчев"), 8,60);
delay(2000);
myOLED.clrScr();
//myOLED.print(("ГОРОД"), 5,14);
myOLED.setCursor(80,55);
myOLED.setFont(MediumFontRus);
myOLED.print("КМ/Ч");
myOLED.autoUpdate(false);
}
//
// Эта функция принимает символ из Serial и возвращает
// указатель на полученную строку или NULL, если строка
// ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
//
static const int MAX_LEN = 120; // 120 - максимальная длина строки - надо посмотреть правильное значение в описании протокола!
char * getStrFromSerial(void) {
static bool waitingForStrBegin = true; // истина, если мы ждём начала строки ($)
static char strBuf[MAX_LEN]; // буфер для строки
static int ptr = 0; // индекс свободного байта в буфере
//
// Если буфер переполнился, печатаем сообщение и начинаем ждать новую строку
//
if (ptr >= MAX_LEN) {
Serial.println("*** Error: Too long string!!!");
ptr = 0;
waitingForStrBegin = true;
return NULL;
}
//
// Если в Serial ничего нет - выходим
// А если есть, то читаем 1 символ
//
if (!Serial.available()) return NULL;
const char c = Serial.read();
Serial.print(c);
//
// Если мы ждём начала строки, то сравинваем
// прочитанный символ с '$', если равен - начало найдено
//
if (waitingForStrBegin) {
if (c == '$') {
ptr = 0;
strBuf[ptr++] = c;
waitingForStrBegin = false;
}
return NULL;
}
//
// Если прочитанный символ - перевод строки или возврат каретки
// то считаем, что строка закончилась. Возвращаем её,
// а сами готовимся ждать новую.
//
if (c == '\r' || c == '\n') {
strBuf[ptr] = '\0';
waitingForStrBegin = true;
return strBuf;
}
//
// Просто записываем символ в строку
//
strBuf[ptr++] = c;
return NULL;
}
//
// Читаeм долготу и широту, складывает в lon и lat
// Возвращает true, если прочитала и false если нет
//
bool readLatLon(double & time,double & latitude, double & speed )
{
// getStrFromSerial() вернёт строку, полученную из Serial
// или NULL, если строка ещё пока не получена
//
const char * str = getStrFromSerial();
//
// Если строка ещё не получена, выходим
//
if (str == NULL) return false;
//
// Если строка не начинается с "$GPGGA или GPRMC",
// то она нам не нужна выходим
//
;
const char * prefix = "$GPRMC";
//
//
if ( ! strncmp(str, prefix, strlen(prefix)))
{
char * comma = strchr(str, ',');
//
// Если не нашли (строка кривая пришла?) - выходим
//
if (!comma) return false;
//
// со следующего символа просле запятой идёт числоа - широта
//
time = atof(comma+1);
//
// Ищем вторую запятую после начала числа-широты
//
comma = strchr(comma+1, ','); // сначала ищем первую запятую 2
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 3
if (!comma) return false; // почему-то не нашли :((((
latitude=atof(comma+1);
comma = strchr(comma+1, ','); // сначала ищем первую запятую 4
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 5
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // сначала ищем первую запятую 6
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 7
if (!comma) return false; // почему-то не нашли :((((
speed=atof(comma+1)*1.852; // переводим скорость в км/час
//speed=atof(comma+1);
return true;
}
}
void loop() {
//myOLED.setFont(BigNumbers);
//myOLED.print(speed,30,55,0);
//myOLED.print(gps_speed,30,55,0);
double speed,latitude, time;
//Читаем время,кол-во спутников,,скорость если успешно прочитались, печатаем
if (readLatLon(time, latitude,speed)) {
//speed=gps_speed;
//speed--;
if (digitalRead(5)==HIGH&&flag==0) //по нажатию кнопки включается либо режим
{ // ГОРОД либо ТРАССА
regim++;
flag=1;
if (regim>2) regim=1;
}
if (digitalRead(6)==LOW&&flag==1)
{
flag=0;
}
if (regim==1)
{
myOLED.update();
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
n=1;
speed1=1;
}
if (regim==2)
{
myOLED.update();
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
n=2;
speed1=2;
}
if (digitalRead(6)==HIGH&&flag2==0 ) // по нажатию кнопки выключается либо включается OLED дисплей
{ // через полевой транзистор
flag2=1;
digitalWrite(9,!digitalRead(9));
if (n==1)
{
myOLED.begin();
myOLED.print("КМ/Ч",80,55);
regim=1;
}
if (n==2)
{
myOLED.begin();
myOLED.print("КМ/Ч",80,55);
regim=2;
}
}
if (digitalRead(6)==LOW &&flag2==1 )
{
flag2=0;
}
if (speed1==1) //если скорость более 78км/ч моргает светодиод
{ //если менее-гаснет
if (speed>=78 )
{
digitalWrite(7, !digitalRead(7));
}
else
{
digitalWrite(7,LOW);
}
}
if (speed1==2)
{
if (speed>=108) //если скорость более 108км/ч моргает светодиод
{ //если менее-гаснет
digitalWrite(7, !digitalRead(7));
}
else
{
digitalWrite(7,LOW);
}
}
if (latitude>10)
{
myOLED.setCursor(95,14);
myOLED.setFont(MediumFontRus);
myOLED.print("GPS",90,14); //выводим кол-во спутников
}
else myOLED.print("NON",90,14);
if (speed<100 && speed>10) // тут при выводе скорости, если число двухзначное
{ // закрашиваем младший разряд
// myOLED.drawRect (59, 28, 78, 57, true , 0);
//myOLED.print(" ",59,40);
//myOLED.print(" ",59,55);
}
if (speed<10)
{
myOLED.update();
//myOLED.drawRect (44, 28, 78, 57, true , 0);
myOLED.print(" ",44,40);
myOLED.print(" ",44,55);
}
myOLED.update();
myOLED.setFont(BigNumbers);
myOLED.print(speed,30,55,0); //выводим скорость
//myOLED.print(gps_speed,30,55,0);
Serial.println();
Serial.print("time: ");
Serial.print(time, 2);
Serial.print(" latitude: ");
Serial.print(latitude,0);
//Serial.print(" date: ");
//Serial.println(date, 0);
Serial.print(" speed: ");
Serial.print(speed, 4);
}
}
Сейчас меняю скорость порта этим сообщением- ss.print("$PUBX,41,1,3,3,38400,0*24\r\n");
Хватает до первого выключения питания.
Там может и не быть возможности сохранять настройки, тогда единственный вариант - прописать эту строчку в Сетап и менять скорость при каждом включении.
Да, настройки слетают через пару часов без питания.
Пробую перехватывать сообщения с u-centre, выходит какой-то бред.
ss.println("$PUBX,40,GSV,0,0,0,0,0,0*59");
ss.println("$PUBX,40,GSA,0,0,0,0,0,0*4E");
ss.println("$PUBX,40,VTG,0,0,0,0,0,0*5E");
ss.println("$PUBX,40,ZDA,0,0,0,0,0,0*44");
ss.println("$PUBX,40,GLL,0,0,0,0,0,0*5C"); //Отключаем все посылки кроме GLL и RMC
ss.write(message1, sizeof(message1)); //set 5Hz
//ss.write(message2, sizeof(message2)); //save settings. Это не обязательно. Без сохранения будет работать до отключения питания с приёмника
Еще один вопрос знатокам) Вот код.
Но мне надо закрасить на экране при выводе скорости два правых разряда, чтобы при скорости менее 10км/ч на дисплее индицировалось однозначное число.(просто если скорость была более 10км/час то младший разряд остается на экране, вот я и затираю его пробелами). Так вот, при раскомментировании строк 276-277 получается вот такой результат.
Почему то сообщение GPRMC выводится не правильно.Как видно еще и вывод информации идет не строго через 200мс.
Можно ли что то предпринять для устранения данной проблемы?
Еще один вопрос знатокам) Вот код.
Но мне надо закрасить на экране при выводе скорости два правых разряда, чтобы при скорости менее 10км/ч на дисплее индицировалось однозначное число.(просто если скорость была более 10км/час то младший разряд остается на экране, вот я и затираю его пробелами). Так вот, при раскомментировании строк 276-277 получается вот такой результат.
Почему то сообщение GPRMC выводится не правильно.Как видно еще и вывод информации идет не строго через 200мс.
Можно ли что то предпринять для устранения данной проблемы?
Конечно можно . Строка 002 .
Переподключился к аппаратному порту, скорость GPS изменил уже на 9600, порт тоже настроен на 9600, результат тот же.Почему то сообщение когда время 144256,40 пропускается, а перед ним выводится не полностью.
Сейчас меняю скорость порта этим сообщением- ss.print("$PUBX,41,1,3,3,38400,0*24\r\n");
Хватает до первого выключения питания.
Там может и не быть возможности сохранять настройки, тогда единственный вариант - прописать эту строчку в Сетап и менять скорость при каждом включении.
Да, настройки слетают через пару часов без питания.
Пробую перехватывать сообщения с u-centre, выходит какой-то бред.
Скажем это частота 5 Гц, в хексе- B5 62 06 08 06 00 F4 01 01 00 01 00 0B 77
Если пробовать конвертировать в ASCII, то получается какя-то ерунда.
Как вставить это в код? Скорость меняю этой строчкой - ss.print("$PUBX,41,1,3,3,38400,0*24\r\n");
Возможно кому нибудь это пригодиться. Изменение настроек U-Blox
void setup()
{
byte message1[] = {0xB5,0x62,0x06,0x08,0x06,0x00,0xC8,0x00,0x01,0x00,0x01,0x00,0xDE,0x6A};
byte message2[] = {0xB5,0x62,0x06,0x09,0x0D,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x31,0xBF};
Serial.begin(9600);
delay(200);
ss.begin(9600);
ss.println("$PUBX,40,GSV,0,0,0,0,0,0*59");
ss.println("$PUBX,40,GSA,0,0,0,0,0,0*4E");
ss.println("$PUBX,40,VTG,0,0,0,0,0,0*5E");
ss.println("$PUBX,40,ZDA,0,0,0,0,0,0*44");
ss.println("$PUBX,40,GLL,0,0,0,0,0,0*5C"); //Отключаем все посылки кроме GLL и RMC
ss.write(message1, sizeof(message1)); //set 5Hz
//ss.write(message2, sizeof(message2)); //save settings. Это не обязательно. Без сохранения будет работать до отключения питания с приёмника