Адаптер для кнопок руля
- Войдите на сайт для отправки комментариев
Помогите, собираю адаптер для кнопок руля, скачал код а править не умею. Мне нужно лишь одну функцию реализовать, об этом вконце текста
Платформа ардуино мини про
Штуковина работает так: На вход А0, на который подвешено 5v через резистор 2кОм, подается определенное сопротивление. Программа по измеренным на входе напряжениям находит в таблице подстановки желаемую команду (в виде значения конкретного напряжения в вольтах) и скармливает её ЦАПу по I2S Плата ЦАП выдает на выходе AOUT ожидаемые напряжения.
const int inButtons[]={
//resistance kOmhs. To detect volts, you need to consider your pullup resistor and Vcc. I use 1KOhm & 3.3V
// R= V * R0 / (Vcc-V)
280, // MODE
750, // CH UP
1300, // CH DOWN
2120, // VOL UP
3120, // VOL DOWN
4590, // SPEECH
6250, // ON HOOK
8630 // OFF HOOK
};
и потом заполнить таблицу кнопок в соответствия в проге, например у меня такая:
// +10 means that we must add ground to jack ring `
const int maps[8][2]=
{
{ 0, 1 }, // MODE > source/off .off
{ 3,3+10 }, // CH UP > next .fldr up
{ 4,4+10 }, // CH DN > prev .fldr dn
{ 5, 5 }, //VOL UP > vol up .
{ 6, 6 }, //VOL DN > vol dn .att-mute
{ 7+10,0+10}, //SPEECH > voice ctrl .ph.tel menu
//{ 0+10,-1}, //SPEECH > .ph.tel
{ 1+10,1+10 }, //ON HOOk> ph.answer .
{ 2+10,7 } //OFFHOOK> ph.hangup .esc
};
Модуль ЦАП/АЦП, AD\DA на PCF8591
Сам код такой:
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C bus address
#define MAX_INT 32767
#define DEBUG true
const int buttonPin=A0; // monitor voltage here.
const int ringPin=13; // drain to ground for sending additional commands
const int analogInControlPin = A1; // read back pin
int buttonStateStableLoops=0;
const int nStableLoops=4; // wait for N loops until stabilize in volts
int buttonStableState=1024; // 0-1024 from analogRead
int buttonLastState=1024; // the same
int buttonJitter=15; // 1% from 1024
const int nShortPressLoops=10;
const int nLongPressLoops=50;
const int nShortPressLoopsToSend=10;
//const int nShortPressLoops=10;
//const int nLongPressLoops=25;
//const int nShortPressLoopsToSend=15;
bool longPress=false;
bool shortPress=false;
int shortPressLoopsCount=0;
float inVoltage;
int ResistorOhms;
int pressedButtonNr=-1;
int buttonToPressNr=-1;
int RingState=HIGH;
const float outMaxVoltage=5; // greatest V that DAC may produce
const float outDepressedButtonsVoltage=3.3; // greatest V that your unit awaits
const float inMaxVoltage=5; // greatest V that may appears on input line (where pullup resistor was connected)
const float inFactor = inMaxVoltage/1024; // input V to ADC ratio
const float outFactor = outMaxVoltage/255; // ouput V to DAC ratio
const float pullupResistor=2000; // how much Ohms you attach to input pullup
const int inButtons[]={
//resistance kOmhs. To detect volts, you need to consider your pullup resistor and Vcc. I use 1KOhm & 3.3V
// R= V * R0 / (Vcc-V)
280, // MODE
750, // CH UP
1300, // CH DOWN
2120, // VOL UP
3120, // VOL DOWN
4590, // SPEECH
6250, // ON HOOK
8630 // OFF HOOK
};
const float outButtons[]={ //volts on tip // + means ground on jack ring
0.32, // source/off + ph.tel
0.75, // att-mute + ph.answer
1.1, // display + ph.hangup
1.36, // next + fldr up
1.64, // prev + fldr dn
1.92, // vol up
2.22, // vol dn
2.74 // esc + ph.voice ctrl
};
// +10 means that we must add ground to jack ring `
const int maps[8][2]=
{
{ 0, 1 }, // MODE > source/off .off
{ 3,3+10 }, // CH UP > next .fldr up
{ 4,4+10 }, // CH DN > prev .fldr dn
{ 5, 5 }, //VOL UP > vol up .
{ 6, 6 }, //VOL DN > vol dn .att-mute
{ 7+10,0+10}, //SPEECH > voice ctrl .ph.tel menu
//{ 0+10,-1}, //SPEECH > .ph.tel
{ 1+10,1+10 }, //ON HOOk> ph.answer .
{ 2+10,7 } //OFFHOOK> ph.hangup .esc
};
void setup() {
Wire.begin();
if (DEBUG) Serial.begin(230400);
pinMode(ringPin, OUTPUT);
}
bool IsNear(int TestValue,int ReferenceValue,int Deviance) {
if (TestValue>(ReferenceValue+Deviance)) return false;
if (TestValue<(ReferenceValue-Deviance)) return false;
return true;
}
int getNearestResistorNr(int res) {
int iBestIndex=0;
int BestR=MAX_INT;
for (int i=0; i<8; i++) {
if ( abs(res-inButtons[i]) < BestR ) {
iBestIndex=i;
BestR= abs(res-inButtons[i]);
}
}
return iBestIndex;
}
bool SupressJitter() {
int buttonState;
buttonState=analogRead(buttonPin);
if (IsNear(buttonState,buttonLastState,buttonJitter)) {
if ( buttonStateStableLoops!=MAX_INT) buttonStateStableLoops++;
if (buttonStateStableLoops<=nStableLoops)
{ }
else
{
buttonStableState=buttonState;
return true;
}
}
else
{
buttonLastState=buttonState;
buttonStateStableLoops=0;
}
return false; //unstable
}
void sentToDAC(int value) {
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
Wire.write(value); // value to send to DAC
Wire.endTransmission(); // end
}
void sendCommand(int RingState, float Voltage) {
digitalWrite(ringPin,RingState);
sentToDAC(int(Voltage/outFactor));
}
void loop() {
float outVoltage=outDepressedButtonsVoltage;
inVoltage=buttonLastState*inFactor;
ResistorOhms= inVoltage * pullupResistor / (inMaxVoltage-inVoltage);
if ( SupressJitter() ) {
if (IsNear(buttonStableState,976,buttonJitter))
{ // some button was depressed
longPress=false;
if ( shortPress ) {
if ( shortPressLoopsCount==0 ) {
shortPressLoopsCount=nShortPressLoopsToSend;
buttonToPressNr=maps[pressedButtonNr][0];
if ( buttonToPressNr>=10 ) {
buttonToPressNr=buttonToPressNr-10;
RingState=LOW;
} else {RingState=HIGH;}
outVoltage=outButtons[buttonToPressNr];
sendCommand(RingState,outVoltage);
}
shortPressLoopsCount--;
if (shortPressLoopsCount==0) shortPress=false;
}
else {
pressedButtonNr=-1;
sendCommand(HIGH,outDepressedButtonsVoltage);
}
}
else { //some button is pressed
pressedButtonNr=getNearestResistorNr(ResistorOhms);
shortPressLoopsCount=0;
if ( buttonStateStableLoops < nShortPressLoops ) {
// do nothing
}
else {
if ( buttonStateStableLoops < nLongPressLoops ) {
longPress=false;
shortPress=true;
}
else {
longPress=true;
shortPress=false;
buttonToPressNr=maps[pressedButtonNr][1];
if ( buttonToPressNr>=10 ) {
buttonToPressNr=buttonToPressNr-10;
RingState=LOW;
} else {RingState=HIGH;}
outVoltage=outButtons[buttonToPressNr];
sendCommand(RingState,outVoltage);
}
}
}
}
if (DEBUG) {
Serial.print("Vin=");
Serial.print((inFactor * analogRead(analogInControlPin)));
Serial.print("\tStable=");
Serial.print(buttonStableState);
Serial.print("\tinVoltage=");
Serial.print(inVoltage);
Serial.print("\tOhms=");
Serial.print(ResistorOhms);
Serial.print("\tpressedButtonNr=");
Serial.print(pressedButtonNr);
Serial.print("\tbuttonToPressNr=");
Serial.print(buttonToPressNr);
Serial.print("\tshortPress=");
Serial.print(shortPress);
Serial.print("\tlongPress=");
Serial.print(longPress);
Serial.print("\tRingState=");
Serial.print(RingState);
Serial.print("\tLoops=");
Serial.print(buttonStateStableLoops);
Serial.println();
}
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(2);
}
А теперь вопрос: Мне нужно добавить кнопку, ну тоесть еще одно резистивное значение на вход ардуинки и на выходе модуля АЦП получить замыкание обычного контакта (как реле)

А теперь вопрос:
Мне нужно добавить кнопку, ну тоесть еще одно резистивное значение на вход ардуинки и на выходе модуля АЦП получить замыкание обычного контакта (как реле)
Вы уверены, что это вопрос? Я перечитал три раза и так и не нашёл здесь вопроса и не понял на что именно Вам нужно ответить.
Ну как же можно не понять вопрос. Нужно добавить кнопку на вход, аналогично ее запрограммировать, и на выходе получить 2 замыкающих независимых контакта, для коммутации чего либо. Вопрос собсно, как это сделать?
Есть два основных варианта:
1. Если Вам нужно быстро получить результат - обратиться в раздел "Ищу исполнителя".
2. Если Вы хотите сделать это самостоятельно, начать с чтения литературы, рекомендованной в теме "Песочница".
первый вариант: За деньги то все могут, а ты попробуй помочь)
Второй вариант для новичка чтобы вкопаться в сложый код, уйдет много дней и ночей и не факт что оно того стоит
Вопрос собсно, как это сделать?
Ну, так собсно этого-то в первом посте и не было.
а ты попробуй помочь)
Так Вы же сами на это предложение и ответили
не факт что оно того стоит
Если для Вас "не факт", что это это нужно, то уж для нас-то и подавно.
Странно у вас тут заведено, просишь помощи, а в ответ нам это не надо иди в платную ветку. Хорошо что я не программист и если меня спросят, что по электронике, то я помогаю бесплатно и трачу на много времени)
См. п.№5 здесь.
Ладно, подожду желающего помчь, я уверен, там ничего сверхсложного нет, и понимающий потратит немного своего драгоценного времени. А ему потом другие помогут в чем нибудь другом, закон такой есть круговорота)
Удачи!
первый вариант: За деньги то все могут, а ты попробуй помочь)
Второй вариант для новичка чтобы вкопаться в сложый код, уйдет много дней и ночей и не факт что оно того стоит
"Чтобы вкопаться в сложный код" у НЕ_НОВИЧКА тоже уйдет некоторое время. И теперь предложите мне хоть одну причину, почему, например я должен "вкапываться" в ваш код, вместо того чтоб заниматься своими делами?
Это форум тех, кому интересно разобраться в Ардуине и смежных областях и научится что-то делать самому. Если у вас такой цели (разобраться и научиться) - нет и вы хотите "просто добавить кнопку на руль" - самое просто е и эффективное будет заказать работу в платном разделе. За 2-3 дня и 2-5 тыс рублей кто-нибудь с удовольствием решит вашу проблему
b707
Для вас видимо нет причин кому то и что-то просто так тут помогать, не тратьте свое драгоценное время на писанину в этой теме. А на платный запрос тут и до вас намекали, но поверьте мне, это устройство стоит сущие копейки и я занимаюсь им только из своего любопытства к ардуинке, еслиб небыло интереса в этом разбираться, то уже давно бы все спаял на простых радиодеталях
еслиб небыло интереса в этом разбираться, то уже давно бы все спаял на простых радиодеталях
А если бы был интерес, то и разбирался бы, а не клянчил бы готовое решение на форуме.
Ворота
Думаешь я не пробовал разобраться? толку то сидеть и неделями в одного разбираться, и не факт что получится еще.
Я бы с удоваольствием поразбирался бы с кем-нибудь, пока желающих не видно, зато заниматься писаниной пустой это святое дело и время свое драгоценное тратить на это, вас тут много таких))
Думаешь я не пробовал разобраться?
Думаю - нет.
Если бы пытался, то выложил бы свои попытки с пояснением что пошло не так и конкретными вопросами. И, кстати, сразу получил бы другое отношение к себе и вопрос был бы давно решён.