Непонятки с аналоговым входом

Hrom29
Offline
Зарегистрирован: 27.09.2020

Помогите разобраться с проблемой. Предистория. После установки нештатной магнитолы на авто захотелось управлять с руля ею. Поиски по сети дали скетч и описание устройства конвертирующего резистивные кнопки руля в команды понятные магнитоле. Вроде все правильно собрал проошил ардуину и тут началось самое интересное. После нажатия на кнопку на руле начинается хаотичное переключение команд на магнитоле. Смотрю на компе. Видит отсутствие сопротивления потом подключаемое сопротивление а потом сыпет разными уровнями сопротивлений без остановки. Отключил , включил опять ноль до следующего нажатия. Входа менял, кондёр на них вешал, не меняется ситуация вообще. https://yadi.sk/d/tBYvNG5LB7YXJQ
Скетч прикрепил.
Добавлю ещё пару моих наблюдений. На выходе АЦП висит всегда при нулевом сопротивлении 0,60 вольта. Питание для пин А0 делал отдельное. Ардуину питал по разному. И юсб и 5 вольт и 12 вольт. Ситуация не меняется.
Надеюсь на помощь.

Online

nik182
Offline
Зарегистрирован: 04.05.2015

А скетч где?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

И схема где?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Hrom29 пишет:
Помогите разобраться с проблемой. Предистория. После установки нештатной магнитолы на авто захотелось управлять с руля ею. Поиски по сети дали скетч и описание устройства конвертирующего резистивные кнопки руля в команды понятные магнитоле. Вроде все правильно собрал проошил ардуину и тут началось самое интересное. После нажатия на кнопку на руле начинается хаотичное переключение команд на магнитоле. Смотрю на компе. Видит отсутствие сопротивления потом подключаемое сопротивление а потом сыпет разными уровнями сопротивлений без остановки. Отключил , включил опять ноль до следующего нажатия. Входа менял, кондёр на них вешал, не меняется ситуация вообще. https://yadi.sk/d/tBYvNG5LB7YXJQ Скетч прикрепил. Добавлю ещё пару моих наблюдений. На выходе АЦП висит всегда при нулевом сопротивлении 0,60 вольта. Питание для пин А0 делал отдельное. Ардуину питал по разному. И юсб и 5 вольт и 12 вольт. Ситуация не меняется. Надеюсь на помощь. Online

#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);
}

 

Hrom29
Offline
Зарегистрирован: 27.09.2020

Спасибо. Я так и не понял как крепить скетч. Схема проста на пин А0 2 ком с 5 вольт подтяжку и на кнопки руля через минус . АЦП по I2C. Вот и вся схема.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Hrom29 пишет:
Спасибо. Я так и не понял как крепить скетч. Схема проста на пин А0 2 ком с 5 вольт подтяжку и на кнопки руля через минус . АЦП по I2C. Вот и вся схема.
Похоже на бред. Рисуйте нормально. Не ленитесь.

b707
Offline
Зарегистрирован: 26.05.2017

Hrom29 пишет:
Спасибо. Я так и не понял как крепить скетч.

прикрепление кода на форум - это простейший " идиотен-тест". Если ты не справился даже с этим - стоит ли пытаться двигаться дальше?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Для начала нужно научиться понятно для собеседника изъясняться. Я больше половины не понял. И схемы нет, и кода нет, и не понятно изъясняешься. Как помогать?

Гриша
Offline
Зарегистрирован: 27.04.2014

ИМХО. Есть подозрение, что не все так просто как кажется.

Hrom29 пишет:
на пин А0 2 ком с 5 вольт подтяжку и на кнопки руля через минус . АЦП по I2C. Вот и вся схема.

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

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

и прочитайте первые 2 поста и скетч загрузится на сайт и картинки вставятся 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Гриша пишет:
где стоит подтяжка... я понял что на руле, требуется несколько точнее.

Ясен пень -  подтяжка на руле, а радиостанция на бронепоезде.

Гриша пишет:
г

По сути, проблема 

в том, что ТС давно сказали "рисуй схему", но ему это нахрен не нужно, а нужно только Вам и тем, кто как и Вы, трут свой ХШ, пытаясь угадать на каком там транзисторном бронепоезде у него подтяжки лопнули.

Hrom29
Offline
Зарегистрирован: 27.09.2020

Простите за не понятливость(((. Просто с телефона нихрена не вставляется. Доберусь домой до компа исправлюсь.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Гриша пишет:

ИМХО. Есть подозрение, что не все так просто как кажется.

Hrom29 пишет:
на пин А0 2 ком с 5 вольт подтяжку и на кнопки руля через минус . АЦП по I2C. Вот и вся схема.

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

Вот на этом тоже моя "понятливость" закончилась. Без схемы и кода никак не понять что именно "лажает".

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

Feofan
Offline
Зарегистрирован: 28.05.2017

Кто-то может объяснить мне запись, к примеру, в строке #63 - для чего тут сложение {3, 3+10}?

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
};

 

Hrom29
Offline
Зарегистрирован: 27.09.2020

http://magnitola.org/pioneer/324908-universalnoe-reshenie-dlya-podklyuch...
Вот отсюда взял исходники. Чем классная схема так это тем что позволяет расширить возможности кнопок руля.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Hrom29 пишет:
Вот отсюда взял исходники. Чем классная схема так это тем что позволяет расширить возможности кнопок руля.
И чем недостаток, кнопки должны быть буквально в 2см от аналогового входа Ардуины. Для случая когда подтяжка на руле, а радиостанция на бронепоезде не подходит.

Feofan пишет:
Кто-то может объяснить мне запись, к примеру, в строке #63 - для чего тут сложение {3, 3+10}?
Ну это для того что бы неокрепшые умы смущать ленью более продвинутых товарищей.  Ну лень складывать два числа. Компьютер мощный он сам все сложит и запишет.

Гриша
Offline
Зарегистрирован: 27.04.2014

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

Гриша
Offline
Зарегистрирован: 27.04.2014

BOOM пишет:

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

Та вы шо?!!! кнопки на руле - самое главное! они еще и стоят копейки  не дорого!!! 

Hrom29
Offline
Зарегистрирован: 27.09.2020

Гриша пишет:

BOOM пишет:

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

Та вы шо?!!! кнопки на руле - самое главное! они еще и стоят копейки  не дорого!!! 


А вы знаете как в Луганск везутся товары с того же Али (((( или как привезти тот же АЦП (((( это по поводу кнопок.
Спасибо большое за информацию.

Гриша
Offline
Зарегистрирован: 27.04.2014

Hrom29 пишет:

 А вы знаете как в Луганск везутся товары с того же Али (((( или как привезти тот же АЦП (((( это по поводу кнопок. Спасибо большое за информацию.

Hrom29, для вас пост выше, схему и код - если помощи хотите.

Hrom29
Offline
Зарегистрирован: 27.09.2020
#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
  1209, // CH UP
  3000,  // CH DOWN
  263, // VOL UP
  683, // VOL DOWN
  053, // SPEECH
  6250, // ON HOOK
  2000   // 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);
}

 

Hrom29
Offline
Зарегистрирован: 27.09.2020

вот код правленый под мои хотелки кнопки.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А где кнопки-то? Их нет на схеме.

Hrom29
Offline
Зарегистрирован: 27.09.2020

Key1 + key2 это резистивные кнопки на руле. Через минус

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

А для чего АЦП ???

sadman41
Offline
Зарегистрирован: 19.10.2016

А он им напряжение делает. Этот модуль ещё и ЦАП.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Hrom29 пишет:
Key1 + key2 это резистивные кнопки на руле. Через минус

Значит, или Вы рисуете схему полностью, вместе со всеми кнопками и резисторами, или Вам придётся пройти лесом как только народу надоест клещами вытягивать из Вас что же там у Вас такое.

Мне уже надоело, до свиданья.

Когда Вам это будет настолько нужно, что будет не лень ради этого схему нарисовать, тогда приходите.