Доработка радар-детектора под скрытую установку

Pinin
Offline
Зарегистрирован: 17.05.2011

Есть такой девайс - Stinger S650. Всем хорош, но при включении питания он по своему алгоритму работы начинает режим самотестирования. Когда он используется "as is", это может быть, и не напрягает, но при полной интеграции его в машину - это беда: отрубить этот режим можно лишь нажатием нескольких кнопок на корпусе, а когда он спрятан под торпедо...

Опять же, учитывая наличие компа в машине - глупо выводить какие-то "железные" кнопки куда быто ни было - посему была задача написать прогу для управления устройством через комп и задействовать под управление всем этим Арду.

Полный отчет о том, что из этого получилось можно прочитать здесь: carpc-project.ru/How-it-made.html (статья "Stinger S650" в прокручивающемся меню). С удовлетворением могу заметить, что работает все как часы - поставил и забыл.

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Давайте учше саму статью сюда. Просто если это реклама стороннего ресурса - удалю. Так как по вашей ссылке не показывает ровным счетом ничего, пишет: "Извините, но для просмотра этой страницы у Вас недостаточно прав.
Вы должны авторизоваться или пройти регистрацию." 

Будем все признательны за интересный проект

Pinin
Offline
Зарегистрирован: 17.05.2011

Да нет, это не реклама - просто там все очень подробно расписано (и по железу, и по софту) + много иллюстраций. Ну не вопрос - если так, вечером попробую и здесь отписаться. Вряд ли получится столь же подробно, но хоть листинги приведу...

А на счет регистрации - статьи доступны и без нее (сейчас специально проверил): просто надо пролистать список и выбрать нужную (синие кнопочки с названиями статей, ездят влево/вправо при подведении к ним курсора). ;)

Zaliv
Offline
Зарегистрирован: 05.03.2011

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

Pinin
Offline
Зарегистрирован: 17.05.2011

2 Zaliv

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

Pinin
Offline
Зарегистрирован: 17.05.2011

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

РД разобран

Это сам РД без корпуса. Как видите, доработки паяльником минимальны. Индикатор (на снимке он в самом низу платы) тоже будет демонтирован и вынесен в другое место.

Сама Арду смонтирована на отдельной плате (обвязка минимальна - оптроны да резисторы подтяжки, благо схема цифровая полностью):

Сам РД впоследствии был установлен в торпедо (конструкция позволила поместить его так, что кроме пластика ничто более не загораживает ему обзор, а тот, как известно, радиопрозрачен). Индикатор же, вместе с частью отпиленного корпуса был помещен вниз центральной консоли:

И на глазах не маячит, и увидеть всегда можно (сининький экранчик около ручки АКПП).

Вот такая получилась система: сам РД спрятан под колпаком монитора, индиктор его родной - внизу консоли, управление всем этим добром - через тач компа.

Если прошивка Арду делалась через компилятор Arduino 0018, то прогу управления для компа сделал с помощью Processing 1.0.9

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

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

Alexander
Offline
Зарегистрирован: 25.04.2010

Молодец автор, просто мастер, аккуратненько так все получилось.
Добавления кода с сохранением форматирования второй кнопочкой над редактором сообщения. Такая иконка с красными скобочками и надписью code. Если код длинный, то на второй закладке диалога добавления кода удобно пометить сворачивать код.

Pinin
Offline
Зарегистрирован: 17.05.2011

Да я знаю как код добавлять - просто гарантированно рабочих листингов в тот момент под рукой не было. Теперь есть - выкладываю.

 

Прошивка Арду:

/*
  Семь кнопок: 
  Вкл/Выкл питания нагрузки
  Режим 1 (короткое нажатие)
  Режим 1 (длинное нажатие)
  Режим 2 (короткое нажатие)
  Режим 2 (длинное нажатие)
  Громкость +
  Громкость -
 
 Питание на нагрузку подается либо при начальной инициализации системы, 
 либо программно (для вкл/выкл нагрузки без снятия питания со всей системы)
 По включению питания формируется импульс сброса самотестирования нагрузки. 
 Громкость выставляется в предустановленный уровень.
 
 The circuit:
 * Оптрон Режима 1  attached from pin 9 to ground 
 * Оптрон Режима 2  attached from pin 11 to ground
 * Оптрон Вкл/Выкл  attached from pin 7 to ground
 * Оптрон "Громкость"  attached from pin 10 to ground
 * pin 8 attached to pin 11   
 * pin 7 attached to pin 12
  
  carpc-project.ru
 modified 22.01.2010
  */

// constants won't change. They're used here to 
// set pin numbers:
const int buttonPin1 = 12;     // Вход с питания
const int buttonPin2 = 8;      // Вход с формирователя сброса
const int buttonPin7 = 6;      // Включение/выключение питания
const int ledPin5 =  9;        // Управление 1 режимом
const int ledPin4 =  11;       // Управление 2 режимом/Ипульс сброса теста
const int ledPin2 =  7;        // Включение нагрузки
const int redPin   = 10;       // Управление громкостью
int val;


// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int redLEDValue   = 50;      // Предустановленный уровень громкости

void setup() {
  Serial.begin(115200);              //установка порта 
  // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin4, OUTPUT); 
  pinMode(ledPin5, OUTPUT);
  pinMode(redPin, OUTPUT);   // sets the pins as output
    // initialize the pushbutton pin as an input:
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin7, INPUT);
  analogWrite(redPin, redLEDValue);

    // turn LED on:    
    digitalWrite(ledPin2, HIGH); // Первое включение системы
   
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin1);

            // Если питание подано, формируется импульс сброса с задержкой 2 сек:
  if (buttonState == HIGH) {     
    // turn LED on: 
   delay(2000);                  // пауза на сброс теста for a 2 second (подбирается вручную)
    digitalWrite(ledPin5, HIGH); // Импульс сброса 1 сек 
   delay(1000);  
  } 
  else {
  }
}

void loop() {
            // Если нагрузка уже инициалирована, переход в рабочую программу
  while (digitalRead(buttonPin1) == HIGH) {
     work(); 
   }
             // Если нагрузка не инициалирована, переход в инициализацию
  while (digitalRead(buttonPin1) == LOW) {
     initial(); 
   }
}
void initial(){   
  delay(1000);                  // пауза на включение
   // Выбор режима Вкл/Выкл:
  if (Serial.available())          //если есть принятый символ, 
  {
    val = Serial.read();            //  то читаем его и сохраняем в val  
   
  buttonState = digitalRead(buttonPin7);
  
  if (val == 'd') {     
    // turn LED on:    
    digitalWrite(ledPin2, HIGH); // Включение питания
     } 
  else {
      }
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin1);

          // Если питание подано, формируется импульс сброса с задержкой 2 сек:
  if (buttonState == HIGH) {     
    // turn LED on: 
   delay(2000);                  // пауза на сброс теста for a 2 second (подбирается вручную)
    digitalWrite(ledPin5, HIGH); // Импульс сброса 1 сек 
   delay(1000);  
  } 
  else {
  }

         // Если импульс сброса сформирован, переход к рабочему циклу
   while (digitalRead(buttonPin2) == HIGH) {
     work(); 
   }
}
}

void work(){
  digitalWrite(ledPin5, LOW); // Снятие импульса сброса
           
           // Выбор режима 1 короткое/длинное нажатие:
  
  if (Serial.available())          //если есть принятый символ, 
  {
    val = Serial.read();            //  то читаем его и сохраняем в val 
  
  
  if (val == '1') {     
    // turn LED on:    
    digitalWrite(ledPin4, HIGH); 
   delay(1000);                  // Короткое нажатие (Реж.1)
  digitalWrite(ledPin4, LOW);    // set the LED off 
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin4, LOW); 
  }
  
  if (val == '3') {     
    // turn LED on:    
    digitalWrite(ledPin4, HIGH); 
   delay(5000);                  // Длинное нажатие (Реж.1)
  digitalWrite(ledPin4, LOW);    // set the LED off 
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin4, LOW); 
  }
            // Выбор режима 2 короткое/длинное нажатие:
  
  if (val == '5') {     
    // turn LED on:    
    digitalWrite(ledPin5, HIGH); 
   delay(1000);                  // Короткое нажатие (Реж.2)
  digitalWrite(ledPin5, LOW);    // set the LED off 
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin5, LOW); 
}

  if (val == '7') {     
    // turn LED on:    
    digitalWrite(ledPin5, HIGH); 
   delay(5000);                  // Длинное нажатие (Реж.2)
  digitalWrite(ledPin4, LOW);    // set the LED off 
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin5, LOW); 
  }
  
  if (val == 'b' && redLEDValue > 1){ // Уменьшение громкости

redLEDValue -= 1; // Red down
}

  if (val == '9' && redLEDValue < 255 ) {  // Увеличение громкости

redLEDValue += 1; // Red up
}

// analogWrite() expects 2 parameters, the object/pin and a value between 0 (off) and 255 (full on)
analogWrite(redPin,   redLEDValue);   // Write current values to LED pins
delay(50); 
  
  
          // Включение/выключение питания:
  
  if (val == 'd') {     
    // turn LED on:    
    digitalWrite(ledPin2, LOW); 
   delay(1000);                  // 
  digitalWrite(ledPin2, LOW);    // set the LED off 
  } 
  else {
  }
  }
}


 Скетч управляющей проги:

import processing.serial.*;   
Serial port;  
int x,y,x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,w1,h1,w6,h6,lock;

PImage bs;     // Все кнопки не нажаты 
PImage dw;     // Все кнопки не нажаты, нажата "DIM" 
PImage dw1;    // Все кнопки не нажаты, нажата "MENU" 
PImage dw2;    // Все кнопки не нажаты, нажата "MUTE" 
PImage dw3;    // Все кнопки не нажаты, нажата "HW/CITY" 
PImage dw4;    // Все кнопки не нажаты, нажата "VOL_UP" 
PImage dw5;    // Все кнопки не нажаты, нажата "VOL_DOWN" 
PImage dw6;    // Все кнопки не нажаты, нажата "ПИТАНИЕ" 

void setup() 
{ 
  port = new Serial(this, "COM5", 115200); // Прописываем COM-порт на котором у вас сидит Carduino 
   
  size(540, 408);//размер окна 
     
  bs = loadImage("BG1.jpg");             //загрузить все кнопки ненажатыми 
  dw = loadImage("DIM.jpg");       //загрузить изображение с нажатой кнопкой "DIM" 
  dw1 = loadImage("MENU.jpg");     //загрузить изображение с нажатой кнопкой "MENU" 
  dw2 = loadImage("MUTE.jpg");     //загрузить изображение с нажатой кнопкой "MUTE" 
  dw3 = loadImage("HW.jpg");       //загрузить изображение с нажатой кнопкой "HW/CITY" 
  dw4 = loadImage("VOL_UP_1.jpg");   //загрузить изображение с нажатой кнопкой "VOL_UP" 
  dw5 = loadImage("VOL_DOWN_1.jpg"); //загрузить изображение с нажатой кнопкой "VOL_DOWN" 
  dw6 = loadImage("7_down.jpg");        //загрузить изображение с нажатой кнопкой "ПИТАНИЕ" 
  w1 = 140;      // Размер малой кнопки по горизонтали 
  h1 = 60;       // Размер  малой кнопки по вертикали 
  w6 = 195;      // Размер большой кнопки по горизонтали 
  h6 = 80;       // Размер большой кнопки по вертикали 
  x = 270;        // Х начальная координата кнопки "DIM" 
  y = 225;       // y начальная координата кнопки "DIM" 
  x1= 120;       // Х начальная координата кнопки "MENU" 
  y1= 145;       // y начальная координата кнопки "MENU" 
  x2= 270;       // Х начальная координата кнопки "MUTE" 
  y2= 145;       // y начальная координата кнопки "MUTE" 
  x3= 120;       // Х начальная координата кнопки "HW/CITY" 
  y3= 225;       // y начальная координата кнопки "HW/CITY" 
  x4= 120;       // Х начальная координата кнопки "VOL_UP" 
  y4= 65;       // y начальная координата кнопки "VOL_UP" 
  x5= 270;       // Х начальная координата кнопки "VOL_DOWN" 
  y5= 65;       // y начальная координата кнопки "VOL_DOWN" 
  x6= 170;       // Х начальная координата кнопки "ПИТАНИЕ" 
  y6= 295;       // y начальная координата кнопки "ПИТАНИЕ" 
  image(bs,0,0); // Нарисовать в окне все кнопки ненажатыми 
  } 


void draw() 
{   
   
  if( mousePressed) 
   { 
    
     // Проверка нажатия в области "DIM" 
     if (mousePressed && (mouseX >= x && mouseX <= x + w1 && mouseY >= y && mouseY <= y + h1)) 
     {
     if(lock==1){image(dw, 0, 0);port.write('1');
     }
     lock=0;
     }
          
     // Проверка нажатия в области "MENU" 
      if (mouseX >= x1 && mouseX <= x1 + w1 && mouseY >= y1 && mouseY <= y1 + h1) 
     {   
     if(lock==1){image(dw1, 0, 0);port.write('3');
     }
     lock=0;
     }
     
     // Проверка нажатия в области "MUTE" 
     if (mouseX >= x2 && mouseX <= x2 + w1 && mouseY >= y2 && mouseY <= y2 + h1) 
     {   
     if(lock==1){image(dw2, 0, 0);port.write('5');
     }
     lock=0;
     }  
     
     // Проверка нажатия в области "HW/CITY" 
     if (mouseX >= x3 && mouseX <= x3 + w1 && mouseY >= y3 && mouseY <= y3 + h1) 
     {   
     if(lock==1){image(dw3, 0, 0);port.write('7');
     }
     lock=0;   
     }  
     // Проверка нажатия в области "VOL_UP" 
     if (mouseX >= x4 && mouseX <= x4 + w1 && mouseY >= y4 && mouseY <= y4 + h1) 
     { 
      port.write('9');
     delay (50); 
     if(lock==1){image(dw4, 0, 0);
     }
     lock=0;    
     }  
     // Проверка нажатия в области "VOL_DOWN" 
     if (mouseX >= x5 && mouseX <= x5 + w1 && mouseY >= y5 && mouseY <= y5 + h1) 
     {  
      port.write('b');
      delay (50);
     if(lock==1){image(dw5, 0, 0);
     }
     lock=0;   
     }  
     // Проверка нажатия в области "ПИТАНИЕ" 
     if (mouseX >= x6 && mouseX <= x6 + w6 && mouseY >= y6 && mouseY <= y6 + h6) 
     {   
     if(lock==1){image(dw6, 0, 0);port.write('d');
     }
     lock=0;    
     }  
        
   }
if(!mousePressed){
if(lock==0){image(bs, 0, 0);lock=1;//port.write('С');
}
}
   
} 

Ну, схемотехника, думаю, понятна - все прописано в самой прошивке. Да и все остальные необходимые комменты там же.

Как показала практика - регулировка громкости динамика в жизни не потребовалась. Поэтому часть, отвечающая за нее формально реализована, но не работает и отлаживать ее не стал (соотношение затрат к полезному результату это не оправдывало). В остальном вопросов к работе этой связки нет: сам РД свои функции как радар-детектор выполняет на 4 с плюсом (так и не понял, насколько корректно он отрабатывает обнаружение ЛИСДов - мало их у нас). Касательно же звена Ардуина-комп вообще все без проблем: добавил испеченную прогу в автозагрузку и написал простенький скин для фронт-энда, встроив ее таким образом в оболочку управления CarPC.

Вспоминаю про все это либо когда надо переключиться с режима "город" на "трассу", либо когда срабатывает ахтунг. Осталось еще научить РД вместо стандартного "Обнаружен сигнал радара в диапазоне..." орать "Готовь бабки!"

 

Есть еще пара задумок по использованию Арду - в карписишном проекте и проекте SmartHome. Но об этом - по мере реализации...

 

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Супер! и Код хорошо коментирован! 5+!!! 

Modular
Offline
Зарегистрирован: 05.03.2011

Впечатлен. Автор молодец.

Pinin
Offline
Зарегистрирован: 17.05.2011

Сенкс! Правда, справедливости ради, должен заметить, что с написанием кода очень существенную помощь мне оказали мои коллеги по писикаровским форумам. За крайние двадцать лет это был мой первый опыт программирования (после универа работа моя связана с разработкой железа, а не программ). Но написание прошивок под Арду - процесс приятный и логичный, да и увлекательный...

AVL4ARDUINO
Offline
Зарегистрирован: 04.01.2012

Всем привет!

Я долго смеялся, как увидел эту тему.

Автору - большое моё уважение, естественно.

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