Объединение двух скетчей и переключение кнопкой.

Denisich2012
Offline
Зарегистрирован: 19.02.2017

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

1. Авто подсос на карбюраторную машину, контроль через датчик хола и термометр, управление через сервопривод, вывод на OLED экран.

2. Ручное управление через энкодер.

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

Скейтч №1.

#include <Wire.h>        // подключение библиотеки для ds18b20
#include <OneWire.h>
//DS18b20
OneWire ds(10);   //подключаем датчик ds18b20 к 10 цифровому входу
#include <OLED_I2C.h>
OLED  myOLED(8, 9, 8); // 8pin - SDA , 9pin - SCL
extern uint8_t RusFont[]; // Русский шрифт
extern uint8_t MegaNumbers[]; // Подключение больших шрифтов
extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русскийх символов.
#include <Servo.h>      //подключение библиотеки для сервопривода
Servo servo;
int potPin = 2; // Порт для провода от датчика холла
int now = 0;// последнее значение сигнала с датчика
long time = 0; // для сохранения времени начала счета импульсов
int count = 0; // колличество импльсов
int val; //временная переменная для считывания сигнала с датчика
bool LampState4 = false;
int flg_push; //флаг прихода импульса
float Temp;
float volts;
int i;
int n;
int analogPin = A0;// порт потенциометра сервопривода
#define LCD_UPDATE_TIME  1000
unsigned long lcdLastUpdateTime = 0;
long updtime = 0;

void setup()
{
  Wire.begin();
  servo.attach(11,130,175);   //подключаем сервопривод к 11 цифровому порту
  myOLED.begin();

}

void loop()
{
  setTemperature(); // вызываем функцию работы с DS18b20
  setOboroti();
}
int setTemperature() // DS18B20
{ byte type_s;
  type_s = 0;
  byte data[2];
  ds.reset();
  ds.write(0xCC);
  ds.write(0x44);

  // обращаемся к датчикам раз в 1000 мс, т.к. 750 может быть недостаточно
  if (millis() - lcdLastUpdateTime > LCD_UPDATE_TIME)
  { lcdLastUpdateTime = millis();

    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    data[0] = ds.read();
    data[1] = ds.read();
    Temp = (data[1] << 8) + data[0];
    Temp = (float)Temp / 16.0;;
  int rawReading = analogRead(analogPin);
float volts = (rawReading-360.0)/106*100;
    // Температура
    
  myOLED.clrScr(); // очищаем экран
  myOLED.setFont(RusFont); // Устанавливаем русский шрифт
  myOLED.print("NTVGTHFNEHF", LEFT, 0); // Выводим надпись "Температура"
  myOLED.print("GJLCJC", LEFT, 55); // Выводим надпись "Обороты"
  myOLED.setFont(SmallFont);
  myOLED.printNumF(Temp,1, RIGHT, 0); // Температура
  myOLED.printNumI(volts, RIGHT, 55); // подсос
  myOLED.setFont(MegaNumbers);
  myOLED.printNumI(i, CENTER, 10); // Обороты
  myOLED.update();
  }
  return Temp;
}
int setOboroti()
{
  //считываем данные с датчика холла
  val = digitalRead(potPin);

  //если пришел импульс
  if ((val == HIGH) && (flg_push == 0))  {
    //флаг ставим в 1
    flg_push = 1;
  }
  //если импульс ушел, то увеличиваем счетчик
  if ((val == LOW) && (flg_push == 1))  {
    //флаг ставим в 0
    flg_push = 0;
    count++;
  }
  //если прошло 500 милисекунд
  now = (millis() - time) / 500;
  if (now == 1) {

    //выводим кол импульсов из расчета (об/мин)
    int i = count * 60;
    if (i == 0)
    { if (Temp <= 30) {
        servo.write(130);
      }
      if ((Temp > 30) && (Temp <= 35))
      {
        servo.write(145);
      }
      if ((Temp > 35) && (Temp <= 40))
      {
        servo.write(155);
      }
      if ((Temp > 40) && (Temp <= 50))
      {
        servo.write(165);
      }
      if (Temp > 50)
      {
        servo.write(175);
      }
    }
    else
    {
      if ((Temp <= 30))
      {

        if (i > 1900)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }
      if ((Temp > 30) && (Temp <= 35))
      {
        if (i > 1600)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }
      if ((Temp > 35) && (Temp <= 40))
      {
        if (i > 1400)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }

      if ((Temp > 40) && (Temp <= 50))
      {
        if (i > 1200)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }

      if (Temp > 50)
      {
        servo.write(175);
        servo.detach();
      }
    }
    //сбрасываем начальный счетчик
    time = millis();
    //сбрасываем количество импульсов
    count = 0;
  }
  return i;
}

Скейтч №2.

#include <Servo.h> //Подключаем библиотеку для сервопривода.
Servo Servo;//"Называем" сервопривод.
int ServoPos = 145; //Угол поворота сервопривода.    
int PosLevel = 3; //Значение, на которое будет изменятся угол сервопривода.
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 7;    //Пин, к которому подключен энкодер.  
const int pin_B = 6;    //Пин, к которому подключен энкодер.  
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
 
void setup()  
{
  Servo.attach(11,117,175);//Инициализация серво.
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  currentTime = millis();
  loopTime = currentTime; 
} 
 
void loop()  {
  currentTime = millis();
  if(currentTime >= (loopTime + 5)){
    encoder_A = digitalRead(pin_A);    
    encoder_B = digitalRead(pin_B);      
    if((!encoder_A) && (encoder_A_prev)){ 
      if(encoder_B) {
        if(ServoPos + PosLevel <= 175) ServoPos += PosLevel;               
      }   
      else {
        if(ServoPos - PosLevel >= 117) ServoPos -= PosLevel;               
      }   
 
    }   
    encoder_A_prev = encoder_A;     
     
      MyServo.write(ServoPos); //Вращаем сервопривод в зависимости от переменной.
      
    loopTime = currentTime;
    
  }      
            
}

Обьедененый скейтч.

#include <Wire.h>        // подключение библиотеки для ds18b20
#include <OneWire.h>
//DS18b20
OneWire ds(10);   //подключаем датчик ds18b20 к 10 цифровому входу
#include <OLED_I2C.h>
OLED  myOLED(8, 9, 8); // 8pin - SDA , 9pin - SCL
extern uint8_t RusFont[]; // Русский шрифт
extern uint8_t MegaNumbers[]; // Подключение больших шрифтов
extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русскийх символов.
#include <Servo.h>      //подключение библиотеки для сервопривода
Servo servo;
int n;
int ServoPos = 145; //Угол поворота сервопривода.    
int PosLevel = 3; //Значение, на которое будет изменятся угол сервопривода.
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 7;    //Пин, к которому подключен энкодер.  
const int pin_B = 6;    //Пин, к которому подключен энкодер.  
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
int i;
int potPin = 2; // Порт для провода от датчика холла
int now = 0;// последнее значение сигнала с датчика
long time = 0; // для сохранения времени начала счета импульсов
int count = 0; // колличество импльсов
int val; //временная переменная для считывания сигнала с датчика
bool LampState4 = false;
int flg_push; //флаг прихода импульса
float Temp;
float volts;
int analogPin = A0;// порт потенциометра сервопривода
#define LCD_UPDATE_TIME  1000
unsigned long lcdLastUpdateTime = 0;
long updtime = 0;
const int knopkaPin = 4;
const int swichButtonPin=5;
boolean poslSost = LOW;
boolean znachKnopki = LOW;
int dvig = 0;
int counter = 1;

void setup()
{
  Wire.begin();
  servo.attach(11,130,175);   //подключаем сервопривод к 11 цифровому порту
  myOLED.begin();
  pinMode(knopkaPin, INPUT);
  pinMode(swichButtonPin, INPUT);
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  currentTime = millis();
  loopTime = currentTime;
}
boolean debounce(boolean posl)
{
  boolean znach = digitalRead(knopkaPin);
  if (posl!=znach)
  {
    delay(5);
    znach = digitalRead(knopkaPin);
  }
  return znach;
}
void loop()
{ 
if (digitalRead(swichButtonPin) == LOW)
counter++;
else if (counter > 2)
counter = 1;
znachKnopki = debounce(poslSost);
switch (counter)
{
case 1: {firstcode(); break;}
case 2: {secondcode(); break;}
}
}
int firstcode()
{
  currentTime = millis();
  if(currentTime >= (loopTime + 5)){
    encoder_A = digitalRead(pin_A);    
    encoder_B = digitalRead(pin_B);      
    if((!encoder_A) && (encoder_A_prev)){ 
      if(encoder_B) {
        if(ServoPos + PosLevel <= 175) ServoPos += PosLevel;               
      }   
      else {
        if(ServoPos - PosLevel >= 117) ServoPos -= PosLevel;               
      }   
     }   
    encoder_A_prev = encoder_A;     
    servo.write(ServoPos); //Вращаем сервопривод в зависимости от переменной.
    loopTime = currentTime;  
            
}
}
int secondcode()

{
  setTemperature(); // вызываем функцию работы с DS18b20
  setOboroti();
}
int setTemperature() // DS18B20
{ byte type_s;
  type_s = 0;
  byte data[2];
  ds.reset();
  ds.write(0xCC);
  ds.write(0x44);

  // обращаемся к датчикам раз в 1000 мс, т.к. 750 может быть недостаточно
  if (millis() - lcdLastUpdateTime > LCD_UPDATE_TIME)
  { lcdLastUpdateTime = millis();

    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    data[0] = ds.read();
    data[1] = ds.read();
    Temp = (data[1] << 8) + data[0];
    Temp = (float)Temp / 16.0;;
  int rawReading = analogRead(analogPin);
float volts = (rawReading-360.0)/106*100;
    // Температура
    
  myOLED.clrScr(); // очищаем экран
  myOLED.setFont(RusFont); // Устанавливаем русский шрифт
  myOLED.print("NTVGTHFNEHF", LEFT, 0); // Выводим надпись "Температура"
  myOLED.print("GJLCJC", LEFT, 55); // Выводим надпись "Обороты"
  myOLED.setFont(SmallFont);
  myOLED.printNumF(Temp,1, RIGHT, 0); // Температура
  myOLED.printNumI(volts, RIGHT, 55); // подсос
  myOLED.setFont(MegaNumbers);
  myOLED.printNumI(i, CENTER, 10); // Обороты
  myOLED.update();
  }
  return Temp;
}
int setOboroti()
{
  //считываем данные с датчика холла
  val = digitalRead(potPin);

  //если пришел импульс
  if ((val == HIGH) && (flg_push == 0))  {
    //флаг ставим в 1
    flg_push = 1;
  }
  //если импульс ушел, то увеличиваем счетчик
  if ((val == LOW) && (flg_push == 1))  {
    //флаг ставим в 0
    flg_push = 0;
    count++;
  }
  //если прошло 500 милисекунд
  now = (millis() - time) / 500;
  if (now == 1) {

    int i = count * 60;    //выводим кол импульсов из расчета (об/мин)
    
    if (i == 0)
    { if (Temp <= 30) {
        servo.write(n=130);
      }
      if ((Temp > 30) && (Temp <= 35))
      {
        servo.write(n=145);
      }
      if ((Temp > 35) && (Temp <= 40))
      {
        servo.write(n=155);
      }
      if ((Temp > 40) && (Temp <= 50))
      {
        servo.write(n=165);
      }
      if (Temp > 50)
      {
        servo.write(n=175);
      }
    }
    else
    {
      if ((Temp <= 30))
      {

        if (i > 1900)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }
      if ((Temp > 30) && (Temp <= 35))
      {
        if (i > 1600)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }
      if ((Temp > 35) && (Temp <= 40))
      {
        if (i > 1400)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }

      if ((Temp > 40) && (Temp <= 50))
      {
        if (i > 1200)
        {
          n = servo.read();
          n--;
          servo.write(n);
        }
      }

      if (Temp > 50)
      {
        servo.write(n);
      }
    }
    //сбрасываем начальный счетчик
    time = millis();
    //сбрасываем количество импульсов
    count = 0;
  }
  return i;
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Зачем объявлена переменная i (строка 22), если она дальше нигде не используется? По этой причине строка 234 всегда вернет 0.
servo.write(n=165); - это что такое? Справа повернется на угол в 1 градус, а не 165.
В строках 78 и 98 надо void вместо int.

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

Tomasina пишет:
servo.write(n=165); - это что такое? Справа повернется на угол в 1 градус, а не 165.
Почему?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Клапауций так хочет.

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

Ну, разве что.

Denisich2012
Offline
Зарегистрирован: 19.02.2017

i переменная для датчика холла, уверяю вас там нету 0.

n переменная положения сервы, также уверяю вас поворачивает на угол 165.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

То есть вы считаете что это одна и та же переменная ?  Ну-ну...

Denisich2012
Offline
Зарегистрирован: 19.02.2017

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

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

Denisich2012 пишет:

надо думать над кнопкой.

и, шо тут думать? класс титановый велосипед для тактовой кнопки.

Denisich2012
Offline
Зарегистрирован: 19.02.2017

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

int pin = 5;
int regim = 1;
int flag = 0;

void setup()
{
    pinMode(5, INPUT);
}

void loop()

{

  if (digitalRead(5) == HIGH && flag == 0) //если кнопка нажата
    // и перемення flag равна 0 , то ...
  {
    regim++;
    flag = 1;

    if (regim > 2) //ограничим количество режимов
    {
      regim = 1; //так как мы используем только одну кнопку,
      // то переключать режимы будем циклично
    }
  }
  if (digitalRead(5) == LOW && flag == 1) //если кнопка НЕ нажата
    //и переменная flag равна - 1 ,то ...
  {
    flag = 0; //обнуляем переменную
  }
  switch (regim)
  {
    case 1: {secondcode();break;}
    case 2: {setOboroti();break;}
  }

 

vvadim
Offline
Зарегистрирован: 23.05.2012

ну Клапауций вам уже подсказал)))

не нравится его велосипед - есть готовые библиотеки OneButton, ClickButton и другие...

в сети куча информации на тему разных типов нажатий тактовой кнопки

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

Не уверен что вам это поможет, но все таки скетч здесь https://yadi.sk/d/kbuEZgWr3EeSBT

/*Cl_do_btn_2mode_long.ino
  кнопка 1    ->2 (btn1_pin)  кнопка смена режима
*/
#include "Cl_do_btn_2mode.h"
const byte btn1_pin = 2;
Cl_do_btn_2mode Btn1(btn1_pin);// подключить кнопку на выв 2
void Do1_Btn1() {
  Serial.println("Do1_Btn1");
};
void Do2_Btn1() {
  Serial.println("Do2_Btn1");
};
void DoLong_Btn1() {
  Serial.println("DoLong_Btn1");
};
void setup() {
  Serial.begin(9600);
  Btn1.setup(& Do1_Btn1);

}
void loop() {
  Btn1.loop(& Do1_Btn1, & Do2_Btn1, &DoLong_Btn1);
}

 

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

vvadim пишет:

не нравится его велосипед - есть готовые библиотеки OneButton, ClickButton и другие...

чем не нравится и чем он(велосипед) не готовая библиотека?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Клапауций 823 пишет:

vvadim пишет:

не нравится его велосипед - есть готовые библиотеки OneButton, ClickButton и другие...

чем не нравится и чем он(велосипед) не готовая библиотека?

По памяти:

- Код не разнесен по файлам *.h, *.cpp - это надо делать самостоятельно,

- Нет подсветки синтаксиса,

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

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

andriano пишет:

- Код не разнесен по файлам *.h, *.cpp - это надо делать самостоятельно,

ничего разносить не нужно - весь код находится в заголовочном файле.

andriano пишет:

- Нет подсветки синтаксиса,

напиши себе файл keywords.txt и брось в папку с классом, если тебе это требуется для корректной работы кода - косметическая придирка.

andriano пишет:

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

так же невозможно, если кнопки являются частью приборной панели танка Т-80 или иного девайса отличного от контроллера AVR - придумай что-то поумнее.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Клапауций, не задавай вопросы, если не хочешь слушать на них ответы.

А то тут оказываешь любезность, а в ответ получаешь кучу неудовольствия...

Denisich2012
Offline
Зарегистрирован: 19.02.2017

От вас помощи как спросить больного здоровье, ничего нормально объяснить не можете только мат и критика, из всего что я спросил получил только ссылки и предложение прикрутить на банальную кнопку кучу лишнего кода плюс библиотеку, надо то всего лишь чтоб кнопка работала по длинному нажатию. Дребезг я и аппаратно уберу с помощью RC-фильтра и триггера Шмидта. Вы господа похерили саму идею форумов, где люди обращаются за помощью. Я посижу пара вечеров поучу мат часть и сам напишу скетч, только нахрен оно мне нужно чтоб один раз залить код в машину и забыть про него.

Большое вам спасибо за помощь!!!!!!!!!!!

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Denisich2012 пишет:

Вы господа похерили саму идею форумов, где люди обращаются за помощью. 

Хм... Основная идея форумов - это общение по интересам, а не обязательная помощь всем страждущим.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Denisich2012 пишет:

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

У Клапауция это есть. Если Вы не можете воспользоваться готовым кодом - это Ваши проблемы.

Цитата:

Вы господа похерили саму идею форумов, где люди обращаются за помощью.

Кто Вам сказал эту глупость?

Если Вы пришли за кодом - Вам в раздел "Ищу исполнителя".

Остальные разделы форума - для общения по интересам, а не для потакания халявщикам.

Цитата:

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

Вот это правильно.

Только, когад напишете, сюда его выкладывать не нужно.

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

Denisich2012 пишет:

Я посижу пара вечеров поучу мат часть и сам напишу скетч, 

Вот это правильно! Слова мужчины

Denisich2012 пишет:

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

Не нужно - не делайте. Здесь собираются люди, которым это нужно и интересно. Вы, наверное, песочницей ощиблись.

Denisich2012 пишет:

Большое вам спасибо за помощь!!!!!!!!!!!

Не за что, заходите ещё.

 

 

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

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Да, нет, дорогой, это ты похерил идею форума – места, где люди общаются по интересам. Судя по твоей фразе «только нахрен оно мне нужно …» интереса к этому делу у тебя нет, ну а тогда чего сюда припёрся?

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

andriano пишет:

Клапауций, не задавай вопросы, если не хочешь слушать на них ответы.

на риторические вопросы не нужно отвечать.

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

Denisich2012 пишет:

От вас помощи как спросить больного здоровье, ничего нормально объяснить не можете только мат и критика, из всего что я спросил получил только ссылки и предложение прикрутить на банальную кнопку кучу лишнего кода плюс библиотеку, надо то всего лишь чтоб кнопка работала по длинному нажатию. Дребезг я и аппаратно уберу с помощью RC-фильтра и триггера Шмидта.

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