$GPVTG, x.x, T x.x, M x.x, N x.x, K *hh <CR><LF>
1. Направление курса в градусах, T
2. Магнитное склонение в градусах, М
3. Скорость над поверхностью (SOG) в узлах, N = узлы
4. Скорость над поверхностью (SOG) в км/ч, К = км/ч
5. hh Контрольная сумма строки (обязательно)
Пример сообщения:
$GPVTG,217.5,T,208.8,M,000.00,N,000.01,K*4C
Ну допустим я достану отсюда скорость в км/час, но я хочу ввести еще поправку +3км/час
Даже если и спидометр автомобиля завышает, все равно хотелось бы привести и ту и эту скорость к одной величине.
Спидометры всех гражданских авто ВСЕГДА завышают. И это не случайность - это в законе прописано.
Кроме того, чаще всего они завышают неравномерно, чем выше скорость - тем больше прибавка. выше 100 кмч редко у какой легковушки спидометр не врет +10-15 кмч. Так что идея прибавлять именно 4 кмч - довольно сомнительна.
Кроме того, чаще всего они завышают неравномерно, чем выше скорость - тем больше прибавка. выше 100 кмч редко у какой легковушки спидометр не врет +10-15 кмч.
Хорошо, убедили. Буду считать что скорость GPS точна.
Вот отладил код, все хорошо когда вывожу данные в com порт через Serial.print. Но при попытке вывести скорость и кол-во спутников на дисплей данные не выводятся. Предполагаю что дело в переменных.Вывод на дисплей организован в строках 219-222. И при таком коде почему то не выводятся данные в COM порт через Serial.print
#include <SoftwareSerial.h>
#include <iarduino_OLED.h>
#include <MsTimer2.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 57600;
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 speed;
void setup(void) {
Serial.begin(9600);
ss.begin(GPSBaud);
pinMode(7, OUTPUT);
//MsTimer2::set(90, flash); // 500ms period
pinMode(9,OUTPUT);
digitalWrite(9,HIGH);
delay(200);
myOLED.begin();
myOLED.setFont(MediumFontRus); // Указываем шрифт который требуется использовать для вывода цифр и текста.
myOLED.print(F("УРАГАН-13"), 8,24);
myOLED.print(F("Клеменчев"), 11,60);
delay(2000);
ss.begin(GPSBaud);
//Serial.begin(9600);
myOLED.setFont(MediumFontRus);
myOLED.clrScr();
myOLED.print(("ГОРОД"), 5,14);
n=1;
}
//
// Эта функция принимает символ из Serial и возвращает
// указатель на полученную строку или NULL, если строка
// ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
//
static const int MAX_LEN = 160; // 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 & num_sat, double & date , double & gps_speed )
{
//
// getStrFromSerial() вернёт строку, полученную из Serial
// или NULL, если строка ещё пока не получена
//
const char * str = getStrFromSerial();
//
// Если строка ещё не получена, выходим
//
if (str == NULL) return false;
//
// Если строка не начинается с "$GPGGA или GPRMC",
// то она нам не нужна выходим
//
const char * prefix = "$GPGGA";
const char * prefix2 = "$GPRMC";
if ( ! strncmp(str, prefix, strlen(prefix)))
{
// Ищем первую запятую в строке str
//
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; // почему-то не нашли :((((
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; // почему-то не нашли :((((
//
// со следующего символа просле запятой идёт числоа - долгота
//
num_sat = atof(comma+1);
return true;
}
// Вроде всё
//
else if ( ! strncmp(str, prefix2, strlen(prefix2)))
{
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; // почему-то не нашли :((((
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; // почему-то не нашли :((((
gps_speed=atof(comma+1)*1.852; // переводим скорость в км/час
comma = strchr(comma+1, ','); // сначала ищем первую запятую 8
if (!comma) return false; // почему-то не нашли :((((
comma = strchr(comma+1, ','); // теперь ищем вторую запятую 9
if (!comma) return false; // почему-то не нашли :((((
date=atof(comma+1);
//return true;
}
else return false;
}
void loop(void) {
double time,num_sat, gps_speed,date;
myOLED.setCursor(80,55);
myOLED.setFont(MediumFontRus);
myOLED.print("КМ/Ч");
//Читаем время,кол-во спутников,дату,скорость если успешно прочитались, печатаем
if (readLatLon(time,num_sat, date,gps_speed)) {
Serial.print("time: ");
Serial.println(time, 2);
Serial.print("num_sat: ");
Serial.println(num_sat, 0);
Serial.print("date: ");
Serial.println(date, 0);
Serial.print("speed: ");
Serial.println(gps_speed, 0);
myOLED.setFont(MediumFontRus);
myOLED.print(num_sat,103,14,0);
myOLED.setFont(BigNumbers);
myOLED.print(gps_speed,30,55,0);
}
}
Я вот не понимаю Вас (не значит, что это плохо, просто мне непонятно). Какой кайф в том, что сделает кто-то другой? По мне так - это полный отстой. Делать нужно самому (и да, иногда у меня уходят месяцы на борьбу с каким-нибудь сраным ОУ, которому вздумалось греться). Но просить, чтобы за меня сделали ... Блин, да сделанное другими я и готовое купить могу - проще, дешевле и быстрее, только вот оно мне надо?
Согласен с Вами, мне тоже интересно, просто я завис уже пять дней, чувствую что сам не разберусь. На библиотеке TinyGPS сделал все как хотел, но там слишком медленная скорость,9600, не подходит для машины слишком медленно. Вот по Вашим примерам кое чего добился. Осталось все вывести на дисплей, не думал что возникнет проблема, а она блин возникла.
Вы очень торопитесь. Я не шутил, когда сказал про месяцы. С программированием-то у меня нет проблем, а вот со схемотехникой - безо всяких преувеличений, иные мелкие (по меркам профессионалов) затыки отнимают недели и месяцы, я не шучу.
Подскажите как изменить частоту на приёмнике Unlox neo-M8N. Как поменять скорость порта я нашёл, а частоту передачи что-то не найти. Через U-centre меняет, но после выключения питания всё слетает, так как на плате не припаяна память.
Сейчас меняю скорость порта этим сообщением- ss.print("$PUBX,41,1,3,3,38400,0*24\r\n");
Хватает до первого выключения питания.
Там может и не быть возможности сохранять настройки, тогда единственный вариант - прописать эту строчку в Сетап и менять скорость при каждом включении.
Но мой GPS занижает скорость на 4км/час, т.е мне надо прибавить еще 4км/час.Но тогда при нулевой скорости у меня на дисплее будет индицироваться 4км/час.
Если Ваше первое предложение верно, то никакой "нулевой" скорости не может быть в принципе. А если она вдруг появляется, значит, Ваше первое предложение не соответствует истине.
Если же Вы хотите, чтобы Ваш прибор показывал не истинную скорость, а ту, что показывает автомобильный спидометр, почитайте ГОСТ на спидометры, чтобы выяснить, по какому алгоритму тот завышает показания и, соответственно, примените этот алгоритм к показаниям своего датчика.
Коллеги, добился я вывода необходимых мне данных с частотой 5Гц, т. е каждые 200мс,но после добавления в код других условий( стоит две кнопки, светодиод, OLED дисплей), частота получения данных от GPS разу снижается, вывод сообщений происходит то через 400мс, то через 800мс.Ясно, что код жрёт, это можно победить или нет? И параллельно вопрос, не могу через аппаратный serial вывести информацию о данных с GPS на дисплей. Подключаю правильно, RX-TX, TX-RX.
Коллеги, добился я вывода необходимых мне данных с частотой 5Гц, т. е каждые 200мс,но после добавления в код других условий( стоит две кнопки, светодиод, OLED дисплей), частота получения данных от GPS разу снижается, вывод сообщений происходит то через 400мс, то через 800мс.Ясно, что код жрёт, это можно победить или нет? И параллельно вопрос, не могу через аппаратный serial вывести информацию о данных с GPS на дисплей. Подключаю правильно, RX-TX, TX-RX.
Вот привожу кусочек из LOOP,который существенно подтормаживает вывод данных gps.Приемник gps подключен к ардуино через SoftSerial( D4,D3), через аппаратный Serial(D1,D0) подкдючал, данные gps вообще не выводятся на дисплей. А код с парсингом NMEA сообщения Вы видели, тем более я его копировал из Вашего урока) Сегодня кстати испытывал в машине при езде, так вот почему то кол-во спутником не верное, скачет беспрерывно, и скорость при движении то 0 то правильная, думаю это зависит не от качества приема сигнала gps, аваидимо не много не правильно у меня выводятся данные о скорости и спутниках.
void loop(void) {
double time, speed,num_sat, date;
//Читаем время,кол-во спутников,дату,скорость если успешно прочитались, печатаем
if (readLatLon(time,num_sat, date,speed))
{
if (digitalRead(5)==HIGH&&flag==0) //по нажатию кнопки включается либо режим
{ // ГОРОД либо ТРАССА
regim++;
flag=1;
n=1;
if (regim>2) regim=1;
}
if (digitalRead(6)==LOW&&flag==1)
{
flag=0;
}
if (regim==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=1;
}
if (regim==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=2;
}
if (digitalRead(6)==HIGH&&flag2==0 ) // по нажатию кнопки выключается либо включается OLED дисплей
{ // через полевой транзистор
flag2=1;
digitalWrite(9,!digitalRead(9));
if (n==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
if (n==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
myOLED.begin();
}
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);
}
}
myOLED.setCursor(95,14);
myOLED.setFont(MediumFontRus);
myOLED.print(0);
myOLED.print(num_sat,110,14,0); //выводим кол-во спутников
if (speed<100) // тут при выводе скорости, если число двухзначное
{ // закрашиваем младший разряд
myOLED.drawRect (59, 28, 78, 57, true , 0);
}
if (speed<10)
{
myOLED.drawRect (44, 28, 78, 57, true , 0);
}
myOLED.setFont(BigNumbers);
myOLED.print(speed,30,55,0); //выводим скорость
//Serial.print("time: ");
//Serial.println(time, 2);
//Serial.print("num_sat: ");
//Serial.println(num_sat,0);
//Serial.print("date: ");
//Serial.println(date, 0);
//Serial.print("speed: ");
//Serial.println(speed, 0);
}
}
Закрашивать прямоугольник на дисплее функцией drawrect - это очень медленно. Выводить в эту позицию пробел - в несколько раз (или даже в десятки раз) быстрее.
За этот небольшой кусочек кода 5 раз выбирается один и тот же экранный фонт. Зачем? - выбирайте фонт только тогда, когда он реально меняется
Состояние кнопки на пине 6 проверяется дважды - отдельно для режима город и для режима трасса. Сделайте один раз - а уж после этого выбирайте режим.
Ну и вообще, написано как курица лапой накарябала. сорри :)
Кстати. судя по коду. вы делайте предупреждайку о превышении скорости против гаишных камер. А оно надо? В большинстве регистраторов с GPS и почти во всех навигаторах эта функция уже встроена. Более того, щас почти каждый смартфон имеет ЖПС. скачайте программку с маркета и пользуйтесь ...
Да, это просто сигнализатор превышения скорости в городе и на трассе, первысил заданный порог-загорелся светодиод, ну можно еще птщплку поставить, например с писком на 1сек.Штрафы замучали, смотреть постоянно на спидометр не удобно, антирадар имеется, но хочется просто-загорелась лампочка-сбавь скорость, и не надо снимать с торпеды.А эти антирадары, регистраторы с GPS у меня в районе надо снимать-дураков хватает.Телефон-не интересно).
Выводить в эту позицию пробел - в несколько раз (или даже в десятки раз) быстрее.
А как Вы думаете, если в этом коде ошибка при парсинге сообщений? Просто сегодня проверял в действии конкретно это код, как писал выше спутники не правильно выводятся, и скорость то 0 то реальная.
//#include "timer-api.h"
//#include <MsTimer2.h>
#include <iarduino_OLED.h>
#include <SoftwareSerial.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 57600;
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;
//int _timer = TIMER_DEFAULT;
void setup(void) {
//timer_init_ISR_1Hz(TIMER_DEFAULT);
//Serial.begin(115200);
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("Клеменчев"), 11,60);
delay(2000);
myOLED.clrScr();
myOLED.print(("ГОРОД"), 5,14);
//myOLED.print("КМ/Ч",80,55);
//MsTimer2::set(90, flash); // 500ms period
}
//
// Эта функция принимает символ из Serial и возвращает
// указатель на полученную строку или NULL, если строка
// ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
//
static const int MAX_LEN = 140; // 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 & num_sat, double & date , double & speed )
{
// getStrFromSerial() вернёт строку, полученную из Serial
// или NULL, если строка ещё пока не получена
//
const char * str = getStrFromSerial();
//
// Если строка ещё не получена, выходим
//
if (str == NULL) return false;
//
// Если строка не начинается с "$GPGGA или GPRMC",
// то она нам не нужна выходим
//
const char * prefix = "$GPGGA";
const char * prefix2 = "$GPRMC";
if ( ! strncmp(str, prefix, strlen(prefix)))
{
// Ищем первую запятую в строке str
//
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; // почему-то не нашли :((((
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; // почему-то не нашли :((((
//
// со следующего символа просле запятой идёт числоа - долгота
//
num_sat = atoi(comma+1);
return true;
}
// Вроде всё
//
else if ( ! strncmp(str, prefix2, strlen(prefix2)))
{
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; // почему-то не нашли :((((
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=85;
// comma = strchr(comma+1, ','); // сначала ищем первую запятую 8
//if (!comma) return false; // почему-то не нашли :((((
//comma = strchr(comma+1, ','); // теперь ищем вторую запятую 9
//if (!comma) return false; // почему-то не нашли :((((
date=atof(comma+1);
//return true;
}
else return false;
}
void loop(void) {
double time, speed,num_sat, date;
//myOLED.setCursor(80,55);
//myOLED.setFont(MediumFontRus);
//myOLED.print("КМ/Ч");
//if (num_sat<4) speed=0;
//myOLED.setCursor(80,55);
//myOLED.setFont(MediumFontRus);
//myOLED.print("КМ/Ч");
//myOLED.print(("ГОРОД"), 5,14);
//Читаем время,кол-во спутников,дату,скорость если успешно прочитались, печатаем
if (readLatLon(time,num_sat, date,speed)) {
if (digitalRead(5)==HIGH&&flag==0) //по нажатию кнопки включается либо режим
{ // ГОРОД либо ТРАССА
regim++;
flag=1;
n=1;
if (regim>2) regim=1;
}
if (digitalRead(6)==LOW&&flag==1)
{
flag=0;
}
if (regim==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=1;
}
if (regim==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=2;
}
if (digitalRead(6)==HIGH&&flag2==0 ) // по нажатию кнопки выключается либо включается OLED дисплей
{ // через полевой транзистор
flag2=1;
digitalWrite(9,!digitalRead(9));
if (n==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
if (n==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
myOLED.begin();
}
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);
}
}
myOLED.setCursor(95,14);
myOLED.setFont(MediumFontRus);
myOLED.print(0);
myOLED.print(num_sat,110,14,0);
// myOLED.print(num_sat,103,14,0);
if (speed<100) // тут при выводе скорости, если число двухзначное
{ // закрашиваем младший разряд
myOLED.drawRect (59, 28, 78, 57, true , 0);
}
if (speed<10)
{
myOLED.drawRect (44, 28, 78, 57, true , 0);
}
myOLED.setFont(BigNumbers);
myOLED.print(speed,30,55,0);
//Serial.print("time: ");
//Serial.println(time, 2);
//Serial.print("num_sat: ");
//Serial.println(num_sat,0);
//Serial.print("date: ");
//Serial.println(date, 0);
//Serial.print("speed: ");
//Serial.println(speed, 0);
}
}
Вот еще возник вопрос, можно объявить переменные speed,num_sat,time не локальными а глобальными? Тогда можно вывести все проверки из цикла loop в void skorst() например, или в этом нет особого смысла?
Вот привожу кусочек из LOOP,который существенно подтормаживает вывод данных gps.Приемник gps подключен к ардуино через SoftSerial( D4,D3), через аппаратный Serial(D1,D0) подкдючал, данные gps вообще не выводятся на дисплей. А код с парсингом NMEA сообщения Вы видели, тем более я его копировал из Вашего урока) Сегодня кстати испытывал в машине при езде, так вот почему то кол-во спутником не верное, скачет беспрерывно, и скорость при движении то 0 то правильная, думаю это зависит не от качества приема сигнала gps, аваидимо не много не правильно у меня выводятся данные о скорости и спутниках.
void loop(void) {
double time, speed,num_sat, date;
//Читаем время,кол-во спутников,дату,скорость если успешно прочитались, печатаем
if (readLatLon(time,num_sat, date,speed))
{
if (digitalRead(5)==HIGH&&flag==0) //по нажатию кнопки включается либо режим
{ // ГОРОД либо ТРАССА
regim++;
flag=1;
n=1;
if (regim>2) regim=1;
}
if (digitalRead(6)==LOW&&flag==1)
{
flag=0;
}
if (regim==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=1;
}
if (regim==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=2;
}
if (digitalRead(6)==HIGH&&flag2==0 ) // по нажатию кнопки выключается либо включается OLED дисплей
{ // через полевой транзистор
flag2=1;
digitalWrite(9,!digitalRead(9));
if (n==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
if (n==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
myOLED.begin();
}
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);
}
}
myOLED.setCursor(95,14);
myOLED.setFont(MediumFontRus);
myOLED.print(0);
myOLED.print(num_sat,110,14,0); //выводим кол-во спутников
if (speed<100) // тут при выводе скорости, если число двухзначное
{ // закрашиваем младший разряд
myOLED.drawRect (59, 28, 78, 57, true , 0);
}
if (speed<10)
{
myOLED.drawRect (44, 28, 78, 57, true , 0);
}
myOLED.setFont(BigNumbers);
myOLED.print(speed,30,55,0); //выводим скорость
//Serial.print("time: ");
//Serial.println(time, 2);
//Serial.print("num_sat: ");
//Serial.println(num_sat,0);
//Serial.print("date: ");
//Serial.println(date, 0);
//Serial.print("speed: ");
//Serial.println(speed, 0);
}
}
А как Вы думаете, если в этом коде ошибка при парсинге сообщений? Просто сегодня проверял в действии конкретно это код, как писал выше спутники не правильно выводятся, и скорость то 0 то реальная.
применяй аппаратный сериал !!! больше повторять не буду...
Да я вчера припаял провода, но вот на дисплей данные с GPS не получилолсь вывести.
void setup() {
Serial.begin(57600); // устанавливаем последовательное соединение
}
void loop() {
if (Serial.available() > 0) { // тут далее идет код
......
........
}
Да я вчера припаял провода, но вот на дисплей данные с GPS не получилолсь вывести.
void setup() {
Serial.begin(57600); // устанавливаем последовательное соединение
}
void loop() {
if (Serial.available() > 0) { // тут далее идет код
......
........
}
Как это ты так умудрился подключиться ???
А что не правлиьного в моем подключении?
Игде в вашем (приведенном выше) коде, в "лупе" идет обращение к сериалу ?
То, что запостили пример из учебника, молодец, хоть знаешь, что есть такой учебник ...
Игде в вашем (приведенном выше) коде, в "лупе" идет обращение к сериалу ?
Чот Вы меня совсем запутали. Строка 48.
void setup(void) {
//timer_init_ISR_1Hz(TIMER_DEFAULT);
Serial.begin(57600);
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("Клеменчев"), 11,60);
delay(2000);
myOLED.clrScr();
myOLED.print(("ГОРОД"), 5,14);
//myOLED.print("КМ/Ч",80,55);
//MsTimer2::set(90, flash); // 500ms period
}
//
// Эта функция принимает символ из Serial и возвращает
// указатель на полученную строку или NULL, если строка
// ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
//
static const int MAX_LEN = 140; // 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 & num_sat, double & date , double & speed )
{
// getStrFromSerial() вернёт строку, полученную из Serial
// или NULL, если строка ещё пока не получена
//
const char * str = getStrFromSerial();
//
// Если строка ещё не получена, выходим
//
if (str == NULL) return false;
//
// Если строка не начинается с "$GPGGA или GPRMC",
// то она нам не нужна выходим
//
const char * prefix = "$GPGGA";
const char * prefix2 = "$GPRMC";
if ( ! strncmp(str, prefix, strlen(prefix)))
{
// Ищем первую запятую в строке str
//
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; // почему-то не нашли :((((
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; // почему-то не нашли :((((
//
// со следующего символа просле запятой идёт числоа - долгота
//
num_sat = atoi(comma+1);
return true;
}
// Вроде всё
//
else if ( ! strncmp(str, prefix2, strlen(prefix2)))
{
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; // почему-то не нашли :((((
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=85;
// comma = strchr(comma+1, ','); // сначала ищем первую запятую 8
//if (!comma) return false; // почему-то не нашли :((((
//comma = strchr(comma+1, ','); // теперь ищем вторую запятую 9
//if (!comma) return false; // почему-то не нашли :((((
date=atof(comma+1);
//return true;
}
else return false;
}
void loop(void) {
double time, speed,num_sat, date;
//myOLED.setCursor(80,55);
//myOLED.setFont(MediumFontRus);
//myOLED.print("КМ/Ч");
//if (num_sat<4) speed=0;
//myOLED.setCursor(80,55);
//myOLED.setFont(MediumFontRus);
//myOLED.print("КМ/Ч");
//myOLED.print(("ГОРОД"), 5,14);
//Читаем время,кол-во спутников,дату,скорость если успешно прочитались, печатаем
if (readLatLon(time,num_sat, date,speed)) {
if (digitalRead(5)==HIGH&&flag==0) //по нажатию кнопки включается либо режим
{ // ГОРОД либо ТРАССА
regim++;
flag=1;
n=1;
if (regim>2) regim=1;
}
if (digitalRead(6)==LOW&&flag==1)
{
flag=0;
}
if (regim==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=1;
}
if (regim==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
speed1=2;
}
if (digitalRead(6)==HIGH&&flag2==0 ) // по нажатию кнопки выключается либо включается OLED дисплей
{ // через полевой транзистор
flag2=1;
digitalWrite(9,!digitalRead(9));
if (n==1)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ГОРОД ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
if (n==2)
{
myOLED.setFont(MediumFontRus);
myOLED.print("ТРАССА ", 2,14);
myOLED.print("КМ/Ч",80,55);
}
myOLED.begin();
}
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);
}
}
myOLED.setCursor(95,14);
myOLED.setFont(MediumFontRus);
myOLED.print(0);
myOLED.print(num_sat,110,14,0);
// myOLED.print(num_sat,103,14,0);
if (speed<100) // тут при выводе скорости, если число двухзначное
{ // закрашиваем младший разряд
myOLED.drawRect (59, 28, 78, 57, true , 0);
}
if (speed<10)
{
myOLED.drawRect (44, 28, 78, 57, true , 0);
}
myOLED.setFont(BigNumbers);
myOLED.print(speed,30,55,0);
//Serial.print("time: ");
//Serial.println(time, 2);
//Serial.print("num_sat: ");
//Serial.println(num_sat,0);
//Serial.print("date: ");
//Serial.println(date, 0);
//Serial.print("speed: ");
//Serial.println(speed, 0);
}
}
Друзья, подскажите по коду, прилагаю скрин с ошибкой при выводе результата в com порт и сам код. Ошибка в строке, где стоит цифра 525, это кол-во спутников, как видно до и после показывается корректное число.
#include <iarduino_OLED.h>
#include <SoftwareSerial.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 57600;
//
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;
//int _timer = TIMER_DEFAULT;
void setup(void) {
//timer_init_ISR_1Hz(TIMER_DEFAULT);
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("Клеменчев"), 11,60);
delay(2000);
myOLED.clrScr();
myOLED.print(("ГОРОД"), 5,14);
myOLED.setCursor(80,55);
myOLED.setFont(MediumFontRus);
//myOLED.print("КМ/Ч");
}
//
// Эта функция принимает символ из Serial и возвращает
// указатель на полученную строку или NULL, если строка
// ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
//
static const int MAX_LEN = 170; // 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 & num_sat, double & speed )
{
// getStrFromSerial() вернёт строку, полученную из Serial
// или NULL, если строка ещё пока не получена
//
const char * str = getStrFromSerial();
//
// Если строка ещё не получена, выходим
//
if (str == NULL) return false;
//
// Если строка не начинается с "$GPGGA или GPRMC",
// то она нам не нужна выходим
//
const char * prefix = "$GPGGA";
const char * prefix2 = "$GPRMC";
if ( ! strncmp(str, prefix, strlen(prefix)))
{
// Ищем первую запятую в строке str
//
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; // почему-то не нашли :((((
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; // почему-то не нашли :((((
num_sat = atof(comma+1);
return true;
}
//
//
else if ( ! strncmp(str, prefix2, strlen(prefix2)))
{
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; // почему-то не нашли :((((
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; // переводим скорость в км/час
//return true;
}
else return false;
}
void loop() {
double speed,num_sat, time;
//Читаем время,кол-во спутников,,скорость если успешно прочитались, печатаем
if (readLatLon(time, num_sat,speed)) {
Serial.print("time: ");
Serial.print(time, 2);
Serial.print(" num_sat: ");
Serial.print(num_sat,0);
//Serial.print(" date: ");
//Serial.println(date, 0);
Serial.print(" speed: ");
Serial.println(speed, 4);
}
}
Ну допустим я достану отсюда скорость в км/час, но я хочу ввести еще поправку +3км/час
Даже если и спидометр автомобиля завышает, все равно хотелось бы привести и ту и эту скорость к одной величине.
Спидометры всех гражданских авто ВСЕГДА завышают. И это не случайность - это в законе прописано.
Кроме того, чаще всего они завышают неравномерно, чем выше скорость - тем больше прибавка. выше 100 кмч редко у какой легковушки спидометр не врет +10-15 кмч. Так что идея прибавлять именно 4 кмч - довольно сомнительна.
Именно им) Даже если и спидометр автомобиля завышает...
они все априори завышают на 3-7 км/ч.
у вас есть точный инструмент замера скорости, а вы хотите его уровнять не понятно с чем.
закономерный вопрос - зачем ?
и почему не наоборот ?
вы все время какие-то странные проблемы ставите. Прибавить к скорости +3 кмч - это проблема?
Кроме того, чаще всего они завышают неравномерно, чем выше скорость - тем больше прибавка. выше 100 кмч редко у какой легковушки спидометр не врет +10-15 кмч.
мой гад почти линейный :)
5-7 км/ч в диапазоне 30-120.
вы все время какие-то странные проблемы ставите. Прибавить к скорости +3 кмч - это проблема?
его не устраимает скорость 3 км/ч на неподвижной машине.
его не устраимает скорость 3 км/ч на неподвижной машине.
а он рассчитывает с неподвижного GPS получать строго 0 кмч? - наивно
Хорошо, убедили. Буду считать что скорость GPS точна.
Вот отладил код, все хорошо когда вывожу данные в com порт через Serial.print. Но при попытке вывести скорость и кол-во спутников на дисплей данные не выводятся. Предполагаю что дело в переменных.Вывод на дисплей организован в строках 219-222. И при таком коде почему то не выводятся данные в COM порт через Serial.print
Скорость на может быть в узлах в час - это единица ускорения.
А с GPS скорость приходит и в узлах, и в км/ч берите ту, какая Вам нужна.
С этим я разобрался вроде, спасибо, теперь вот не могу все это вывести на дисплей OLED 128x64. Прблемку описал чуть выше, в посте №58
Выяснил, что при добавлении строк вывода данных на экран, в Serial порту появляется сообщение "ERROR : too long string!!!"
Что бы это значило... и как с этим бороться?
Ну, описал, и молодец. Может кто и отзовётся.
Я вот не понимаю Вас (не значит, что это плохо, просто мне непонятно). Какой кайф в том, что сделает кто-то другой? По мне так - это полный отстой. Делать нужно самому (и да, иногда у меня уходят месяцы на борьбу с каким-нибудь сраным ОУ, которому вздумалось греться). Но просить, чтобы за меня сделали ... Блин, да сделанное другими я и готовое купить могу - проще, дешевле и быстрее, только вот оно мне надо?
Согласен с Вами, мне тоже интересно, просто я завис уже пять дней, чувствую что сам не разберусь. На библиотеке TinyGPS сделал все как хотел, но там слишком медленная скорость,9600, не подходит для машины слишком медленно. Вот по Вашим примерам кое чего добился. Осталось все вывести на дисплей, не думал что возникнет проблема, а она блин возникла.
С этим я разобрался вроде, спасибо, теперь вот не могу все это вывести на дисплей OLED 128x64. Прблемку описал чуть выше, в посте №58
Выяснил, что при добавлении строк вывода данных на экран, в Serial порту появляется сообщение "ERROR : too long string!!!"
Что бы это значило... и как с этим бороться?
строки от №59 до №64
уже пять дней
Вы очень торопитесь. Я не шутил, когда сказал про месяцы. С программированием-то у меня нет проблем, а вот со схемотехникой - безо всяких преувеличений, иные мелкие (по меркам профессионалов) затыки отнимают недели и месяцы, я не шучу.
Выяснил, что как только добавляю строку с библиотеки IArduino_OLED , то сразу ошибки.
Выяснил, что как только добавляю строку с библиотеки IArduino_OLED , то сразу ошибки.
правильно... SoftwareSerial.h не вывозит ...
подключи дефолтный сериал ( 0, 1 ).
Сейчас попробую, я тоже об этом подумал, или еще предположение что библиотеку дисплея установить другую.
Подскажите как изменить частоту на приёмнике Unlox neo-M8N. Как поменять скорость порта я нашёл, а частоту передачи что-то не найти. Через U-centre меняет, но после выключения питания всё слетает, так как на плате не припаяна память.
этот модуль работает на частоте обновлений данных либо 5 либо 10 Герц, надо посмотреть что шлет U-centre в порт при смене частоты.
По дефолту 1 Гц. Уже думал над перехватом сообщения с U-centre.
Я вот так сделал и все работает, правда у меня стоит батарейка.
Я вот так сделал и все работает, правда у меня стоит батарейка.
Там не батарейка, а ионистор. Как я понял он только для сохранения альманаха спутников, для более быстрого старта.
Сейчас меняю скорость порта этим сообщением- ss.print("$PUBX,41,1,3,3,38400,0*24\r\n");
Хватает до первого выключения питания.
Сейчас меняю скорость порта этим сообщением- ss.print("$PUBX,41,1,3,3,38400,0*24\r\n");
Хватает до первого выключения питания.
Там может и не быть возможности сохранять настройки, тогда единственный вариант - прописать эту строчку в Сетап и менять скорость при каждом включении.
Скорость с GPS поступает в узлах в час
Узлы в час - это не скорость, а ускорение.
Но мой GPS занижает скорость на 4км/час, т.е мне надо прибавить еще 4км/час.Но тогда при нулевой скорости у меня на дисплее будет индицироваться 4км/час.
Если Ваше первое предложение верно, то никакой "нулевой" скорости не может быть в принципе. А если она вдруг появляется, значит, Ваше первое предложение не соответствует истине.
Если же Вы хотите, чтобы Ваш прибор показывал не истинную скорость, а ту, что показывает автомобильный спидометр, почитайте ГОСТ на спидометры, чтобы выяснить, по какому алгоритму тот завышает показания и, соответственно, примените этот алгоритм к показаниям своего датчика.
Коллеги, добился я вывода необходимых мне данных с частотой 5Гц, т. е каждые 200мс,но после добавления в код других условий( стоит две кнопки, светодиод, OLED дисплей), частота получения данных от GPS разу снижается, вывод сообщений происходит то через 400мс, то через 800мс.Ясно, что код жрёт, это можно победить или нет? И параллельно вопрос, не могу через аппаратный serial вывести информацию о данных с GPS на дисплей. Подключаю правильно, RX-TX, TX-RX.
поясните, что имеется в виду, а то пока фраза звучит бредово, если учесть, что дисаплей у вас ОЛЕД и никакого сериала в нем нет
Можно. Как именно? ХЗ, т.к. ХЗ что там за код.
Это не вопрос - это утверждение. Принято к сведению, что Вы не можете.
Конечно можно, если код правильно написать .
Вот привожу кусочек из LOOP,который существенно подтормаживает вывод данных gps.Приемник gps подключен к ардуино через SoftSerial( D4,D3), через аппаратный Serial(D1,D0) подкдючал, данные gps вообще не выводятся на дисплей. А код с парсингом NMEA сообщения Вы видели, тем более я его копировал из Вашего урока) Сегодня кстати испытывал в машине при езде, так вот почему то кол-во спутником не верное, скачет беспрерывно, и скорость при движении то 0 то правильная, думаю это зависит не от качества приема сигнала gps, аваидимо не много не правильно у меня выводятся данные о скорости и спутниках.
Предложения оптимизации выложенного кода
Закрашивать прямоугольник на дисплее функцией drawrect - это очень медленно. Выводить в эту позицию пробел - в несколько раз (или даже в десятки раз) быстрее.
За этот небольшой кусочек кода 5 раз выбирается один и тот же экранный фонт. Зачем? - выбирайте фонт только тогда, когда он реально меняется
Состояние кнопки на пине 6 проверяется дважды - отдельно для режима город и для режима трасса. Сделайте один раз - а уж после этого выбирайте режим.
Ну и вообще, написано как курица лапой накарябала. сорри :)
Кстати. судя по коду. вы делайте предупреждайку о превышении скорости против гаишных камер. А оно надо? В большинстве регистраторов с GPS и почти во всех навигаторах эта функция уже встроена. Более того, щас почти каждый смартфон имеет ЖПС. скачайте программку с маркета и пользуйтесь ...
Да, это просто сигнализатор превышения скорости в городе и на трассе, первысил заданный порог-загорелся светодиод, ну можно еще птщплку поставить, например с писком на 1сек.Штрафы замучали, смотреть постоянно на спидометр не удобно, антирадар имеется, но хочется просто-загорелась лампочка-сбавь скорость, и не надо снимать с торпеды.А эти антирадары, регистраторы с GPS у меня в районе надо снимать-дураков хватает.Телефон-не интересно).
А как записать эту строку.
Или это не правильно?
А как записать эту строку.
Или это не правильно?
ну если вы точно вычислили позицию пробеоа (а вы должны были ее вычислить, когда drawrect делали - то такая строчка должна работать
Спасибо, буду пробовать.
А как Вы думаете, если в этом коде ошибка при парсинге сообщений? Просто сегодня проверял в действии конкретно это код, как писал выше спутники не правильно выводятся, и скорость то 0 то реальная.
Вот еще возник вопрос, можно объявить переменные speed,num_sat,time не локальными а глобальными? Тогда можно вывести все проверки из цикла loop в void skorst() например, или в этом нет особого смысла?
Вот привожу кусочек из LOOP,который существенно подтормаживает вывод данных gps.Приемник gps подключен к ардуино через SoftSerial( D4,D3), через аппаратный Serial(D1,D0) подкдючал, данные gps вообще не выводятся на дисплей. А код с парсингом NMEA сообщения Вы видели, тем более я его копировал из Вашего урока) Сегодня кстати испытывал в машине при езде, так вот почему то кол-во спутником не верное, скачет беспрерывно, и скорость при движении то 0 то правильная, думаю это зависит не от качества приема сигнала gps, аваидимо не много не правильно у меня выводятся данные о скорости и спутниках.
Как это ты так умудрился подключиться ???
не думаю что это хорошая идея. ходят разные мнения, мое личное - SoftwareSerial на скоростях выше 38400 работает не стабильно.
Спасибо, буду пробовать.
А как Вы думаете, если в этом коде ошибка при парсинге сообщений? Просто сегодня проверял в действии конкретно это код, как писал выше спутники не правильно выводятся, и скорость то 0 то реальная.
Готовый код аналогичного устройства есть у Алекса Гайвера на Ютубе
Да я вчера припаял провода, но вот на дисплей данные с GPS не получилолсь вывести.
А что не правлиьного в моем подключении?
Готовый код аналогичного устройства есть у Алекса Гайвера на Ютубе
Ой, не надо. Выкладывл он тут свои коды - ни одного без грубейших ошибок ... нафиг-нафиг, чем такое брать за основу, лучше с нуля писать.
Да я вчера припаял провода, но вот на дисплей данные с GPS не получилолсь вывести.
А что не правлиьного в моем подключении?
Игде в вашем (приведенном выше) коде, в "лупе" идет обращение к сериалу ?
То, что запостили пример из учебника, молодец, хоть знаешь, что есть такой учебник ...
Готовый код аналогичного устройства есть у Алекса Гайвера на Ютубе
Ой, не надо. Выкладывл он тут свои коды - ни одного без грубейших ошибок ... нафиг-нафиг, чем такое брать за основу, лучше с нуля писать.
так он же студент, его учит кто-то )))
Чот Вы меня совсем запутали. Строка 48.
все с точностью до наоборот!
Удалено
Друзья, подскажите по коду, прилагаю скрин с ошибкой при выводе результата в com порт и сам код. Ошибка в строке, где стоит цифра 525, это кол-во спутников, как видно до и после показывается корректное число.
Кто или что мешает напечатать введённую строку целиком и посмотреть что в ней?
хм.....извинясь конечно, но как это сделать?
и еще меня смущают строки 149 и 181
надо вывести всю строку и посмотреть, это ошибка при разборе строки или так отдает GPS
Вот благодаря Вашему совету выяснил, что эту туфту выдает gps.
Кол-во спутников в сообщении GPGGA после седьмой запятой. Вопрос, если выход?
Может это из-за того, что надо использовать не SoftSerial а аппаратный?
попробуйте, опустите скорость до 19200