Speedcam informer

PAV
Offline
Зарегистрирован: 29.10.2012

Добрый день.
У меня есть навигатор и я подгрузил в него базу данных по камерам, контролирующих скорость. Очень удобно. Перед камерой притормаживаешь и штраф платить не надо.
Учитывая, что навигатор мне нужен не всегда, а уведомление о камерах всегда, пришла мысль сделать девайс на ардуино, который будет информировать о камерах независимо от других девайсов.

В наличии есть CF GPS Haicom HI-305III, со старого КПК. В блоке ЖПС есть слот для SD карты.
Идея такова – подключить GPS к ардуино, закачать на карточку базу камер, ардуино должен будет считывать базу, определять местоположение и, если впереди на определенном расстоянии, появляется камера сообщать об этом, желательно голосом (впереди камера контролирующая скоростной режим, ограничение скорости 60 км/ч)

Я начинающий, посему прошу помощи у форумчан.
Я вскрыл CF GPS? Но дальше дело не продвинулось, от платы с чипом и слотом сд идет гибкая лента со множеством контактов, как определить за что отвечает каждый контакт не представляю.
Прошу помощи также по следующим пунктам:
Как подключить CF GPS к ардуино?
Как подключить встроенный СД слот к ардуино?
Как научить ардуино подсасывать базу камер и сравнивать с текущим местоположением и определять, что камера например впереди на расстоянии 1 км
Как организовать голосовой вывод?

Я понимаю, что в процессе изучения данного форума и остальных материалов, я найду со временем ответы на большинство вопросов, но если кто-нибудь подскажет, и тем самым облегчит процесс , буду благодарен.

Заранее спасибо

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

По пунктам:
- нужен даташит на ГПС
- найдите схему шилда СД - там и увидите, как подключить. Нужно 4 резистора :)
- запрограммировать ардуино
- купить MP3-shield 

PAV
Offline
Зарегистрирован: 29.10.2012

Спасибо.
С даташитом как раз проблема. Я разобрал, платка похожа на вот такую http://www.haicom.com.tw/EB_204PB.aspx  попробую прозвонить выводы и подключиться. Просто от платки идет шестиконтактный разъем белый пластиковый и шлейф гибкий дополнительно. Я пока не пойму, что от чего, где GPS, а где от SD карточки.
По SD шилду изучаю.
По коду нужна помощь - я понимаю, что мне, для моих целей нужно считать с карточки координату камеры, ее направление и сравнить с текущим положением и направлением, а также со скоростью, дабы определить расстояние до точки, но первое - как это сделать - с if разберусь но как обработать целиком массив? Этих точек там 1000, каждую подгружать и сравнивать?
Чего-то я даже не ебее особо не вижу предложение по mp3 шилду, мож пока пищалкой обойдусь, тут проблем не должно быть.

PAV
Offline
Зарегистрирован: 29.10.2012

Полностью разобрать GPS я не смог, видно, что от платы отходит 3 проводка из 6и пинового разъема и еще лапша.
Однако у GPS есть возможность подключения не только CF, но и Serial (на com порт). Есть проводок, с одной стороны разъемом Mini-1394 для подключения к GPS и с COM и PS/2 с другой стороны для подключения к компьютеру. Данные идут по serial, а с ps/2 берется питание.
Я так понимаю, что я могу использовать SR232 TTL переходник и не заморачиваться?
C другой стороны я понимаю, что разница между RS232 и TTL по сути только в значении напряжения для обозначения единицы и нуля. у одного 12 вольт, у другого 5.
Когда я подключаю GPS в разъем CF моего КПК, я так понимаю, что GPS запитывается 5 вольтами и нормально себя чувствует. 
Вопрос, могу ли я напрямую от ардуины подать на GPS питание 5 вольт и соединить RX TX gPS напрямую  с Arduino?
Не спалит GPS адруину 12 вольтами? Им по идее неоткуда взяться.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Как это неоткуда? а об интегральных преобразователях напряжения слышали? А об умножителях напряжения? Или скажем так. Микруха max232 питается от 5 вольт, где она ±12 берет? (дада! RS232 использует двуполярное напряжение!) Так что найдите любой самый простой преобразователь уровней на транзисторах и подключайте. Даю наводку - программатор АВР для КОМ-порта. 

PAV
Offline
Зарегистрирован: 29.10.2012

Ну вот пока из всего, что вы написали я понял два слова ;)
А я не обойдусь конвертером RS232 TTL  типа такого? - http://www.ebay.com/itm/MAX3232-RS232-Serial-Port-To-TTL-Converter-Modul...

Было бы идеально, если бы подсказали, как реализовать такого рода преобразоватьель. Мож его проще прямо на плате распаять дабы не пользовать сам разъем Serial, для уменьшения размера?
Я в правильном направлении иду? http://www.scienceprog.com/alternatives-of-max232-in-low-budget-projects/

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Да, на правильном. 

mixail844
Offline
Зарегистрирован: 30.04.2012

насчет алгоритма поиска,возмжно я помогу назрело 3 идеи : 
я не знаю  каком формате на SD карточке у вас расположены координаты,но предположу что типа  широта,долгота там есть.
1.классичекий,но самый долгий в плане нахождения координат : используя вложенный цикл поиска-вначале по широте,потом по долготе находите нужные координаты.
2.средненкий:расположить массивы широты и долготы независимо друг от друга в оригинальном порядке,и двумя указателями двух независимых циклов "проходить" по массивам сравнивая с текущими координатами.
3.самый быстрый,как мне кажеться,но не самый легкий в реализации:расположить отдельно массив  широты,и отдельно массив долготы,каждый в возрастающем порядке ,независимо друг от друга.затем используя две независиые переменные в качестве указателей на ячейки в масиве,применить алгоритм Двоичного поиска.

если нужно учесть радиус "разброса" то думаю поможет формула :
 х^2+y^2<=R^2.
где :
х-текущая координата долготы.
y-текущая координата широты
R-нужный радиус,в вашем случае постоянно 1.хотя думаю еще правельней сделать что бы радиус менялся в зависимоси от скорости.
уравнение говорит о чем : есть ли такая координата которая бы решала уравнение.если есть - дать об этом знать.

 

PAV
Offline
Зарегистрирован: 29.10.2012

Подскажите, а я обойдусь просто транзистором, как вот тут внизу на схеме показано, если мне нужно только получать данные с GPS?
http://www.uchobby.com/index.php/2007/06/11/ttl-to-rs232-adaptor-explained/

Т.е. там просто один транзистор 2N3904, и три резистора 10К
Или нужно полностью схему TX RX воспроизводить?

PolzovatelPC
Offline
Зарегистрирован: 09.10.2012

 передавать GPS вы же ничего не собираетесь, соответственного достаточно только RX
з.ы. расскажите как реализуете алгоритм поиска/сравнения координат, у предыдущего коментатора варианты очень интересные, попробовал бы все)

mixail844
Offline
Зарегистрирован: 30.04.2012

mixail844 пишет:

если нужно учесть радиус "разброса" то думаю поможет формула :
 х^2+y^2<=R^2.
где :
х-текущая координата долготы.
y-текущая координата широты
R-нужный радиус,в вашем случае постоянно 1.хотя думаю еще правельней сделать что бы радиус менялся в зависимоси от скорости.
 уравнение говорит о чем : есть ли такая координата которая бы решала уравнение.если есть - дать об этом знать.
 

 
ммда..чуток замудренно слишком упростил хехе,призадумался и оказалось что получилась охинея 

думаю правильней будет так :

(х-х0)^2+(y-y0)^2<=R^2
вот здесь :
х-текущая координата долготы из GPS
х0-сканируемая координата долготы из SD карточки
y-текущая координата широты из GPS
y0-сканируемая координата широты из SD карточки
R-нужный радиус.

PAV
Offline
Зарегистрирован: 29.10.2012

Ага, а нужно еще направление учитывать. Иначе все камеры в радиусе будут срабатывать.
Нотут я думаю можно будет простой IF применить, типа после формулы выше добавить проверку на правильность направления тем камерам, которые попадают в радиус.

Пока реализую железную часть, подскажите, всеж я могу реализовать конвертер RS232>TTL на транзисторе, как на схеме выше, чтобы не пользоваться max232?

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

PAV пишет:

Пока реализую железную часть, подскажите, всеж я могу реализовать конвертер RS232>TTL на транзисторе, как на схеме выше, чтобы не пользоваться max232?

Можете

mixail844
Offline
Зарегистрирован: 30.04.2012

PAV пишет:
Ага, а нужно еще направление учитывать. Иначе все камеры в радиусе будут срабатывать.

 ну и пускай срабатывает.
 береженеого бог бережет,за основу береться факт что камера стоит возле дороги. а не где то в поле и непонятно куда она направлена
ну вот допустим такая ситуация :

программе то небудет известно куда вы намереваетесь повернуть,налево или нарпаво
 а вот скажем,если вы от камеры удаляетесь или приближаетесь,уже учесть можно что бы не сигналило по пусту.

PolzovatelPC
Offline
Зарегистрирован: 09.10.2012

я так понимаю: словил несколько камер на участке в заданном радиусе, получил сигнал, едеш осторожно. и не важно конкретное месторасположение, удалился, все чисто.

PAV
Offline
Зарегистрирован: 29.10.2012

Блин, сел прозванивать GPS. Нашел Rx Tx Gnd V+.  Замерил Tx при подаче напряжения - скачет вокруг 5 вольт. Подключил все напрямую к Arduino - получил вместо координат вот такое x<ÃøxìÃøøøøøøøxfÃøxxüxnÃøøøxxÃfxÌüxó в мониторе порта.
Чешу репу. Причем где-то я уже видел такую проблему, решения только не видел.
Да, еще, когда замеряю напряжение на Rx, получаю значения с минусом, т.е. -5V. Подключаю правильно, перепроверял.
Что это может быть?

PAV
Offline
Зарегистрирован: 29.10.2012

Построил схему с транзистором. Ардуина вообще перестала что-то видеть. Проверил напряжение - пока питание не даю на жпс - мертво 5в. Как подаю питание начинает скакать, причем максимум 5, а минимум ... 2в. т.е. я понимаю ардуино жпс вообще перестало понимать. Почему так? Я надеялся, что схема с транзистором как раз даст мне либо четкий 0 либо 5.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Это разновидность RS232, когда используется не 12, а 5 вольт. Все равно напрямую нельзя. Возможно, нужно проинвертировать сигналы, точно не помню.

PAV
Offline
Зарегистрирован: 29.10.2012

Вот как проинвертировать?

maksim
Offline
Зарегистрирован: 12.02.2012

PAV пишет:
Блин, сел прозванивать GPS. Нашел Rx Tx Gnd V+.  Замерил Tx при подаче напряжения - скачет вокруг 5 вольт. Подключил все напрямую к Arduino - получил вместо координат вот такое x<ÃøxìÃøøøøøøøxfÃøxxüxnÃøøøxxÃfxÌüxó в мониторе порта.
Чешу репу. Причем где-то я уже видел такую проблему, решения только не видел.
Да, еще, когда замеряю напряжение на Rx, получаю значения с минусом, т.е. -5V. Подключаю правильно, перепроверял.
Что это может быть?

Как то странно получается на Rx -5в, а на Tx +5в. Потому как если это RS232, то должно быть и на Rx +/-5в и на Tx +/-5в. То есть на обеих линиях напряжение должно меняться в обе стороны. Скорее всего этого просто не было видно на мультиметре.

У rs232 -12(-5)в - это логическая единица, а +12(+5)в - это логический 0. Вроде как у АВРов имеются защитные диоды на выводах портов и обратное напряжение гасится этими диодами, но лучше поставить диод на линию TX(GPS)-->RX(дуина).

PAV пишет:
Вот как проинвертировать?

Теоретически если приемник всегда что-то отсылает, то при прямом подключении (желательно через диод) примерно так:

#define R4800 474 // задержка
#define RX 2 // подключается ко 2 выводу

void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.write(InvertSerialRead());
}

byte InvertSerialRead(){  // Чтение байта  
  while(!digitalRead(RX));
  byte val = 0;
  delayMicroseconds(R4800/2);
  for(byte offset = 0; offset < 8; offset++){
    delayMicroseconds(R4800);
    val |= !digitalRead(RX) << offset;
  }
  delayMicroseconds(R4800); 
  return val;
}

И попробуйте поиграться задержкой... 

PAV
Offline
Зарегистрирован: 29.10.2012

Спасибо

Пробую в поте лица - полез опять мусор, но уже структурированный - похоже на NIMEA, но другими символами.

Поиграться задержкой - а что такое R4800? Даже гугл не помогает.

А можно сигнал инвертировать хардверно - на уровне эл. схемы?

PAV
Offline
Зарегистрирован: 29.10.2012

Счастье, счастье. Помог вот этот солюшен - http://arduino.cc/forum/index.php/topic,8163.0.html

Получаю данные :))   Переходим ко второму отделению Марлезонского балета ;)

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

PAV пишет:

Поиграться задержкой - а что такое R4800? Даже гугл не помогает.

Это идентификатор, просто буквы и цифры. 

А поиграться надо было так

#define R4800 474 // задержка
#define R4800 470 // задержка
#define R4800 480 // задержка
#define R4800 465 // задержка
#define R4800 485 // задержка

то есть подставлять разные значенися задержки.

Вы лучше в гугле посмотрите что такое #define.

PAV
Offline
Зарегистрирован: 29.10.2012

Да думал, мож чего не знаю и R4800 это какая-то фича.

PAV
Offline
Зарегистрирован: 29.10.2012

Киньте, пожалуйста, солюшеном, как при считывании файла с SD карты присвоить переменным значения, по порядку.

Файл такого вида

IDX,X,Y,TYPE,SPEED,DirType,Direction
218894,37.8580207,55.8196348,5,60,1,70
 

Нужно отбросить первую цифру (до запятой),x = вторая цифра до запятой, y = 3я и т.д. чтобы эти значения можно было потом сравнивать.

Или как лучше сделать для упрощения и ускорения? Я предполагаю, по совету mixail844 для начала попробовать - R я вычислю, зная размер угловой минуты/секунды.

 

mixail844
Offline
Зарегистрирован: 30.04.2012

Если коротко и просто,так как пишу со смарта:скрпировать всю строчку данных во времкнный буффер и там ее разбить при помощи фунции strtok()юзайте гугл.а потои при помощи функции atoi() или atof() перевести в числа для операции над ними

PAV
Offline
Зарегистрирован: 29.10.2012

Вскрыл еще раз GPS прозвонил контакты встроенного ридера SD и выводы CF - получилось странно - штук 40 из 50 - земля (судя по распиновке SD), а остальные не задействованы. Причем в шлейфе, исходящем от платки к выводам  CF, я нужные контакты нащупал, а вот на выводах уже нет. Как так может быть?

 

maksim
Offline
Зарегистрирован: 12.02.2012

Плата может быть многослойной.

PAV
Offline
Зарегистрирован: 29.10.2012

Не могу разобраться. Уже несколькими путями считывал данные с карточки и пытался их разделить, но никак. Почему-то и в нете солюшенов по этому вопросу не вижу (конкретных).

Вот такой код работает, если строку данных задать непосредственно в коде. Как только использую  //char * input = fh.read();  - перестает работать.

Подскажите, как правильно?

данные нужно считать из файла, присвоить переменным значения, которые в файле идут через запятую, как в примере ниже. Главное, чтобы потом с переменными можно было "играться" (умножать, делить)


IDX,X,Y,TYPE,SPEED,DirType,Direction // 
229981,37.3056626,55.6643281,1,60,1,29 // 
#include <SD.h>



void setup() {
  Serial.begin(9600);
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
    
  //проверка на ошибки
  Serial.print("Starting SD...");
  if(!SD.begin(8)) Serial.println("failed");
  else Serial.println("ok");
    File fh = SD.open("test.txt",FILE_READ);
  if(!fh)
  {
    Serial.println("SD open fail");
    return;    
  }
  //char * input = fh.read();
char * input = "$ÇÐÇÇÁ,175341.458,3355.7870,Ó,01852.4251,Å,1,03,5.5,-32.8,Í,32.8,Í,,0000*57";
    char * garbage = strtok(input, ",");
    char * firstNumber = strtok(NULL, ",");
    char * secondNumber = strtok(NULL, ",");
    double firstDouble;
    sscanf(firstNumber, "%lf", &firstDouble);
    printf("%f\n", firstDouble);
    Serial.print(" C = ");
     Serial.println(firstNumber);
  fh.close();
}
void loop() {  
}

 

PAV
Offline
Зарегистрирован: 29.10.2012

Ну подскажите, профи.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Очень не люблю strtok, потому что он не реентрантный, хотя в данном случае по барабану.

"Более другой" (c) вариант - обратить внимание на класс Stream, в нем есть методы parseFloat, например.

Вы иногда видите в примерах, например, такой вариант Seria.parseInt(); это и есть вызов парсера из класса Stream.

Навскидку, либо читать файл через Stream (не знаю, есть ли там FileStream) и сразу парсить, либо читать данные из файла, забивать в Stream, после чего спокойно парсить строку.

Во, наткнулся, класс File в SD библиотеке наследуется от Stream, так у Вас уже всё в кармане! Подумайте.

strtok тоже можно использовать, разумеется, но несколько "сложнее" (всё относительно), зато такой способ меньше памяти скушает, если она Вам нужна. А Stream метод памяти скушает точно больше.

 

PAV
Offline
Зарегистрирован: 29.10.2012

Я уже обдумался, поэтому и прошу помощи. Язык для меня новый, посему просто многих вещей не знаю.

Вот в примере выше конкретный вопрос -  (Вот такой код работает, если строку данных задать непосредственно в коде. Как только использую  //char * input = fh.read();  - перестает работать. Подскажите, как правильно?)

Вот что я там неправильно сделал?

Мне бы для начала получить результат, а код вылизывать я уже потом конечно буду

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Понятно, "потом", тогда я тоже потом.

Тогда Вам еще один совет, больше мешать не буду, посмотрите здесь:

http://arduino.cc/en/Reference/FileRead

Всё просто, RTFM.

 

PAV
Offline
Зарегистрирован: 29.10.2012

    Получился такой код для считывания значений из файла. Проблема в том, что // не являются концом строки и программа продолжает считывать целые даже в коментариях. т.е. первая строка обрабатывается нормально, а потом идет галиматья.

Как ограничить считывание строки до //?

Почему при выводе на монитор порта значение xx округляется до двух знаков после запятой?

float xx1 = x1 / 10000000.0000000;
    float xx = x + xx1;

 

    #include <SD.h>

//229981,37.3056626,55.6643281,1,60,1,29 // Стрелка-СТ -- danny83
//229793,38.7684111,54.5476911,5,90,1,355 // Контроль скорости 90 км/ч, сплошной линии. -- brumo
//229784,38.6287688,55.8520929,5,60,1,92 // Мобильная засада. -- ssd48
//229599,37.5402729,56.0482719,5,40,1,338 // Контроль дорожной разметки при повороте на лево -- nikola65

    void setup() {
        Serial.begin(9600);
        pinMode(10, OUTPUT);
        digitalWrite(10, HIGH);
    
        //�������� �� ������
        Serial.print("Starting SD...");
        if(!SD.begin(8)) Serial.println("failed");
        else Serial.println("ok");
        File fh = SD.open("test.txt", FILE_READ);
        if(!fh)
        {
            Serial.println("SD open fail");
            return;    
        }
while (fh.available()){
          int dal = fh.read();
 // look for the next valid integer in the incoming serial stream:
    int rub = fh.parseInt();
    // do it again:
    float x = fh.parseInt();
    // do it again:
    float x1 = fh.parseInt();
    float xx1 = x1 / 10000000.0000000;
    float xx = x + xx1;
    int y = fh.parseInt();
    long y1 = fh.parseInt();
        float yy1 = y1 / 10000000.0000000;
    float yy = y + yy1;
    int typ = fh.parseInt();
    int sp = fh.parseInt();
    int dirtyp = fh.parseInt();
    int dir = fh.parseInt();

Serial.println("All");
        Serial.println(rub);
        Serial.println(x);
                Serial.println(x1);
                Serial.println(y);
                Serial.println(y1);
                Serial.println(typ);
                  Serial.println(sp);
                Serial.println(dirtyp);
                Serial.println(dir);

                Serial.println("correct");
   }
        fh.close();
    }

    void loop() {
 
}

 

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

PAV пишет:

Как ограничить считывание строки до //?

Я бы подготовил нужный формат заранее:

# echo "тестовая строка // и еще кусочек"| sed s/"\/\/.*"//
тестовая строка

 

или вот так, если хочется "включая"

echo "тестовая строка // и еще кусочек"| sed -E 's/(\/\/).*/\1/'
тестовая строка //

А надежнее - сделать сканер (с засветкой) объективов на местности... :)

PAV
Offline
Зарегистрирован: 29.10.2012

Не хочется заморачиваться каждый раз, лучше помучаться при программировании, но один раз.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

PAV пишет:

Не хочется заморачиваться каждый раз, лучше помучаться при программировании, но один раз.

На c/c++ обработка текста сделана мягко говоря, не самым оптимальным образом. Для этого есть более подходящие языки и утилиты.