Отправка значения кнопки в порт

wenom86
Offline
Зарегистрирован: 04.11.2012

Здравствуйте. Имеется следующий скетч. Если кнопка нажата - загорается светодиод. Нажимаем еще раз и светодиод гаснет. Код проверил-работает. Проблема в том, что не получается отправить данные состояния кнопки в порт. Как только не правлю код - в итоге переходит из состояния 0 в состояние 1  только один раз, а дальше сколько не нажимаю-значение в сериал порту не меняется. Целый день туплю - подскажите как можете.



 
 int flag=0; 

 void setup()    
 { 
        
     pinMode(13, OUTPUT);         
       
         
 } 

 void loop() 

 { 
         
      if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата    
      // и перемення flag равна 0 , то ... 
      { 
            
        digitalWrite(13,!digitalRead(13)); 
        flag=1; 
         //это нужно для того что бы с каждым нажатием кнопки 
         //происходило только одно действие 
         // плюс защита от "дребезга"  100% 
         
      } 
         
       if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата 
      //и переменная flag равна - 1 ,то ... 
      { 
            
         flag=0;//обнуляем переменную flag 
      } 
 } 

 

 

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

Вы не тот код выложили.

wenom86
Offline
Зарегистрирован: 04.11.2012

Вот код.  С 98 по 109 строку искомый код. В 131 строке попытка отправить значение состояния канала.

(еше обратил внимание, что при нажатии кнопки  происходит изменение данных, считанных с аналоговых портов с 500-510 до 520-530 единиц - тоже не пойму с чем связано)



// Передатчик команд управления v3.0
// Органы управления - 4 переменника, 9 кнопок.
// Исполнительные механизмы - 2мотора-вибратора, 1 светодиод

//Цель:
//при нажатии кнопки 1,2,3,4 отправить в сериал-порт информацию о текущем значении.(0 или 1) (кнопка с фиксацией значения)
//при нажатии кнопки 11 отправить в сериал-порт информацию о текущем значении.(0 или 1) (кнопка без фиксации значения)
//при вращении ручки потенциометра 1-4 обработать значения с них и отправить данные в порт для каждого двигателя. (от -100 до 0 и от 0 до 100)
//по каналу управления манипулятором передаются значения (от -100 до 0 и от 0 до 100)
//по каналу управления наклоном камеры передаются значения (от 0 до 100)

#define ANALOG_IN0  0 // Порт, к которому подключен переменный резистор 1
#define ANALOG_IN1  1 // Порт, к которому подключен переменный резистор 2
#define ANALOG_IN2  2 // Порт, к которому подключен переменный резистор 3
#define ANALOG_IN3  3 // Порт, к которому подключен переменный резистор 4

int LeftStickX = 0; // переменная Левого стика - ось X (вниз-вверх)
int LeftStickY = 1; // переменная Левого стика - ось Y (пока неиспользуется)
int RightStickX = 2;// переменная Правого стика - ось X (вперед-назад)
int RightStickY = 3;// переменная Правого стика - ось Y (влево-вправо)

int Pin2 = 2;    //пин 2 используется для включения передачи данных по rs485
int Knopka1 = 3; //кнопка1 подключена к 3 цифровому контакту (освещение 1) (фиксируемая) 
int Knopka2 = 4; //кнопка2 подключена к 4 цифровому контакту (освещение 2) (фиксируемая) 
int Knopka3 = 5; //кнопка3 подключена к 5 цифровому контакту (освещение 3) (фиксируемая) 
int Knopka4 = 6; //кнопка4 подключена к 6 цифровому контакту (освещение 4) (фиксируемая) 
int Knopka7 = 7; //кнопка7 подключена к 7 цифровому контакту (манипулятор - сжать) (нефиксируемая)
int Knopka8 = 8; //кнопка8 подключена к 8 цифровому контакту (манипулятор - разжать) (нефиксируемая)
int Knopka9 = 9; //кнопка9 подключена к 9 цифровому контакту (камера - вверх)
int Knopka10 = 10; //кнопка10 подключена к 10 цифровому контакту (камера - вниз)
int Knopka11 = 11; //кнопка11 подключена к 11 цифровому контакту (резервная) (нефиксируемая)
int MotorPin = 12; //моторы в пульте управления подключены через транзистор к 12 цифровому контакту (пока никак не используются)
int LedPin = 13;   // инициализация светодиода, светодиод в пульте управления подключен к 13 цифровому контакту (пока никак не используются)
int KanalMotoraLevogoGor, KanalMotoraPravogoGor, KanalMotoraPerVert, KanalMotoraZadVert, KanalManip, KanalKamera; 
int KanalKn1, KanalKn2, KanalKn3, KanalKn4; 
int flag1, flag2, flag3, flag4;



void setup() {
  Serial.begin(115200); 
  // Инициализируем цифровые входы/выходы с 3 по 11 в режиме входов.
  pinMode(Knopka1, INPUT);           // назначить выводу порт ввода
  digitalWrite(Knopka1, HIGH);       // активируем подтягивающий резистор 20ком к питанию.
  pinMode(Knopka2, INPUT);           //.......
  digitalWrite(Knopka2, HIGH);
  pinMode(Knopka3, INPUT);        
  digitalWrite(Knopka3, HIGH);
  pinMode(Knopka4, INPUT);        
  digitalWrite(Knopka4, HIGH);
  pinMode(Knopka7, INPUT);        
  digitalWrite(Knopka7, HIGH);
  pinMode(Knopka8, INPUT);        
  digitalWrite(Knopka8, HIGH);
  pinMode(Knopka9, INPUT);        
  digitalWrite(Knopka9, HIGH);
  pinMode(Knopka10, INPUT);        
  digitalWrite(Knopka10, HIGH);
  pinMode(Knopka11, INPUT);        
  digitalWrite(Knopka11, HIGH);
  pinMode(LedPin, OUTPUT);        // Инициализируем 13 выход под светодиод.
}

void loop() 
{
  // -----------------НАЧАЛО СЧИТЫВАНИЙ ПОКАЗАНИЙ СТИКОВ И ОТПРАВКА ЗНАЧЕНИЙ В ПОРТ-----------------
  LeftStickX = analogRead (ANALOG_IN0);   
  LeftStickY = analogRead (ANALOG_IN1);   
  RightStickX = analogRead (ANALOG_IN2);
  RightStickY = analogRead (ANALOG_IN3);
  Serial.print ("LeftStick-X ");
  Serial.println (LeftStickX);
  Serial.print ("LeftStick-Y ");
  Serial.println (LeftStickY);
  Serial.print ("RightStick-X ");
  Serial.println (RightStickX);
  Serial.print ("RightStick-Y ");
  Serial.println (RightStickY);
  Serial.println ("---------");
  delay(500);              // Задержка включается только при проверке работоспособности осей стиков. 
                               // Для включения задержки необходимо раскомментировать строку
                               // Просматривать значения можно в Мониторе порта
  // -----------------КОНЕЦ СЧИТЫВАНИЙ ПОКАЗАНИЙ СТИКОВ И ОТПРАВКА ЗНАЧЕНИЙ В ПОРТ-----------------   
  // -----------------НАЧАЛО ПРЕОБРАЗОВАНИЯ ДАННЫХ С КНОПОК И ПЕРЕМЕННИКОВ В ФОРМАТ ДЛЯ ПЕРЕДАЧИ ПО SERIAL-----------------
     
     // (-) канал вперед-назад-влево-вправо)
     RightStickX = constrain(RightStickX, 20, 1000);
     RightStickY = constrain(RightStickY, 20, 1000);
     KanalMotoraLevogoGor = map(RightStickX, 20, 1000, 100, -100);
     KanalMotoraPravogoGor = map(RightStickX, 20, 1000, 100, -100);
     
     
     // (+) начало обработки канала погружения-всплытия)
     LeftStickX = constrain(LeftStickX, 20, 1000);
     KanalMotoraPerVert = map(LeftStickX, 20, 1000, 100, -100);
     KanalMotoraZadVert = map(LeftStickX, 20, 1000, 100, -100);
     
     // (-) канал кнопки 1
     if(digitalRead(Knopka1)==LOW&&flag1==0) //если кнопка нажата и переменная flag равна 0 , то ... 
      {
       digitalWrite(13,!digitalRead(13)); 
       flag1=1;
       KanalKn1=flag1;     
      } //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие, плюс защита от "дребезга"  100%                  
     if(digitalRead(Knopka1)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна 1 ,то ... 
      {
      flag1=0;
      KanalKn1=!flag1;
      }  //обнуляем переменную flag 






      // (+) канал кнопки 11


  // -----------------КОНЕЦ ПРЕОБРАЗОВАНИЯ ДАННЫХ С КНОПОК И ПЕРЕМЕННИКОВ В ФОРМАТ ДЛЯ ПЕРЕДАЧИ ПО SERIAL-----------------
  // -----------------НАЧАЛО ПЕРЕДАЧИ ПРЕОБРАЗОВАННЫХ И ОБРАБОТАННЫХ ДАННЫХ ПО SERIAL-----------------
  digitalWrite (Pin2, HIGH);                // активация передачи данных по rs485
  Serial.print('a');                        //метка начала передачи значения канала "а"
  Serial.println(KanalMotoraLevogoGor);     //.......
  Serial.print('b'); 
  Serial.println(KanalMotoraPravogoGor);      
  Serial.print('c');
  Serial.println(KanalMotoraPerVert);      
  Serial.print('d'); 
  Serial.println(KanalMotoraZadVert);      
  Serial.print('e');
  Serial.println(KanalKn1);
  Serial.print('f'); 
  Serial.println(!Knopka2);   
  Serial.print('g'); 
  Serial.println(!Knopka3);   
  Serial.print('h'); 
  Serial.println(!Knopka4);    
  Serial.print('i'); 
  Serial.println(KanalManip);              
  Serial.print('j'); 
  Serial.println(KanalKamera);             
  Serial.print('k'); 
  Serial.println(!Knopka11);       
  Serial.println("------------------END------------------");  //конец передачи. 
  // -----------------КОНЕЦ ПЕРЕДАЧИ ПРЕОБРАЗОВАННЫХ И ОБРАБОТАННЫХ ДАННЫХ ПО SERIAL-----------------
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

wenom86, посмотрите свежим взглядом на строчки 102-103 и 107-108. Если кнопка нажата, вы поднимаете флаг, и присваиваете его значение переменной , т.е. каналкн = 1. Как только отпустили кнопку флаг вы сбрасываете, а каналкн присваиваете значение инвертированного флага, т.е. опять он становится единицей.

wenom86
Offline
Зарегистрирован: 04.11.2012

Сделал

  KanalKn1=flag1;

но теперь при нажатии отправляется 1, а при отпускании кнопки -сразу 0. 

 

(Также не пойму в чем дело-при  нажатии кнопки происходит изменение данных, считанных с аналоговых портов с 500-510 до 520-530 единиц.)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

wenom86, правильно, вы же считали состояние кнопки, а она в единице только в момент нажатия. Если нужно не состояние кнопки, а состояние того выхода, которым ей управляете -то переменную каналкн можно вообще убрать, пишите в блоке вывода сразу состояние выхода, и всё. Serial.println (digitalRead(13)); А по поводу изменения показаний analogRead -судя по всему это наводка. Провода до аналогового входа нужно укоротить или экранировать, или изменить схему включения, что бы резистор "на землю" был прямо на входе контроллера.

wenom86
Offline
Зарегистрирован: 04.11.2012

спасибо, буду пробовать.

Такой вопрос, у меня переменники, подключенные к analogRead, находятся на расстоянии 2 метров от ардуины, в общем пульте с кнопками. А кнопки подключены не к +, а к земле, и подтяжка включена в виде встроенного резистора 20ком в ардуину. 

Есть-ли нюансы в подключении кнопки на питание или на землю, может правильнее к питанию?

Встречал в интернете информацию о желательно воздержаться использовать встроенные резисторы подтяжки - как считаете?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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