1. Уважаемый Гость! При написании вопросов в раздел форума [ArduCopter] Вопросы, проблемы и решения обязательно придерживаться шаблона сообщения, оговоренного в правилах раздела! Если сообщение не будет оформлено должным образом, то и ответ на вопрос будет с наименьшим приоритетом. Старайтесь дать максимально полную информацию по вашей проблеме, чтобы можно было более детально рассматривать вопрос!
    Скрыть объявление
  2. Уважаемый Гость! Хотите получать кэшбэк с покупок в online-магазинах? Сервис "Zozi.ru" дает такую возможность!
    Скрыть объявление
  3. Друзья! Для нашего ресурса необходим дополнительный объем пространства в облаке Dropbox. Подробнее.
    Скрыть объявление

Arduino и AVR (Atmel) микроконтроллеры

Тема в разделе "Наши другие увлечения", создана пользователем raefa, 9 мар 2016.

Реклама. Купить это место.
  1. raefa

    raefa Главнокомандующий Команда форума

    Регистрация:
    3 янв 2015
    Сообщения:
    4.324
    Город:
    Zhigulevsk
    Имя:
    Александр
    Последнее редактирование: 19 окт 2017
  2. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Можно. Но в режиме "сделайте всё за меня" вряд ли получится - любое измерение скорости завязано на прерывания, тут уж придётся разобраться.
     
  3. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    Ясно. Но всё не планировалось изначально кабы... :whistling: Я могу пару кнопок нажать :thumbsup:
     
  4. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    А вот такой вопрос можно (если что, могу бартер предложить)?:

    Нашёл кусочек почти подходящий для тахометра, но хочу для спидометра слепить..
    Там в описании вот так: rpm = rpmcount * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30. \

    Если у меня на редукторе 6 магнитов, это же 6 импульсов за оборот, соответственно нужно не 60 написать, а 10? Чота я засомневался, т.к. тогда в сериалпорт (код выводит в сериалпорт, как выводить на индикатор еще не думал) идёт вроде как больше чем надо, ведь не могу же я тюлюпать магнитиком перед датчиком холла на 30-40кмч... или могу...?
     
  5. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    а с чего вы взяли, что один оборот соответствует одному километру в час?
     
  6. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    да я чота не подумал про километры сразу... голова забита уже этими ужасами :unsure:
    Буду подбирать методом тыка вопчем.
    У меня сейчас что-то снова индикатор мигать стал первой слева цифрой, хотя данные вроде выводятся такие как надо.
    Я код взял тот что выше вы мне подсказали (без задержек пока), только добавил туда считывание с цифрового входа с датчика холла

    Код:
    // read RPM
    int latchPin = 8;     //Пин "защелки" первого регистра подключен к ST_CP входу первого регистра отвечающего за сегменты
    int clockPin = 12;    //Пин подключен к SH_CP входу 74HC595
    int dataPin = 11;     //Пин подключен к DS входу 74HC595
    
    int TimeLight = 5;  //время для разогрева сегментов
    //int sensorPin=2;
    
    byte SegDisplay; // переменная для вывода символов на индикаторе
    byte RazrDisplay; // переменная для включения разрядов
    //unsigned long timer, count, timerMeasure, countMeasure;
    // Настройка комбинации для отображения каждого номера на дисплее.
    // Комбинация выбрана на основе таблицы отображаемого знака данным порта
    // Соответственно { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , dp, - }
    byte g_digits[12]={192,249,164,176,153,146,130,248,128,144,127,255}; //массив цифр, генерирующий из сегментов цифры
    byte g_registerArray[2]={2,1}; //массив цифр, указывающий разряды
    int disp = 0; //создаем переменную для вывода на экран
    
    //-----------------------------------------------------------
    
    volatile int rpmcount = 0; //see http://arduino.cc/en/Reference/Volatile
    int rpm = 0;
    unsigned long lastmillis = 0;
    
    void setup(){
      // обозначаем все пины как выходы
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(13, OUTPUT);
      //  analogueValue = digitalRead(sensorPin);
      //--------------------------------------
      Serial.begin(9600);
      attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2).
    }
    
    void loop(){
    
      if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
    
        detachInterrupt(0); //Disable interrupt when calculating
    
        rpm = rpmcount * 6; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.
    
        Serial.print("RPM =\t"); //print the word "RPM" and tab.
        Serial.print(rpm); // print the rpm value.
        Serial.print("\t Hz=\t"); //print the word "Hz".
        Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or enter.*/
    
        rpmcount = 0; // Restart the RPM counter
        lastmillis = millis(); // Uptade lasmillis
        attachInterrupt(0, rpm_fan, RISING); //enable interrupt
      
    
        disp = (rpm);  // вывод на индикатор
        // Разбиваем цифру по разрядам индикатора
        if (disp < 10) // если наша цифра меньше 10, то
        {
          Indicate(0, 11); // пишем в первый разряд пусто
          Indicate(1, disp); // пишем во второй разряд нашу цифру
        }
        if (disp > 10) // если наша цифра меньше 7, то
        {
          digitalWrite(13, HIGH);
          //    else if (disp > 10)
          //    {
          //    delay(250);              // wait for a second
          //    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
          //    delay(250);              // wait for a second
        }
        else if (disp > 10); // если наша цифра больше 10, то
    
        Indicate(0, disp / 10); // пишем в первый разряд - цифру делёную на 10
        Indicate(1, disp % 10); // пишем во второй разряд цифру оставшуюся от деления на 10
        /*
    Допустим наша цифра 25.
         Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае,
         у нас не остаются. Таким образом мы имеем в третем разряде цифру 2.
         В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления.
         В нашем случае это и есть та самая 5.
         Аналогичным образом разбивается наша цифра и далее.
         */
      }
    
    }
    
    void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
      rpmcount++;
    }
    
    //-------------------------------------------------------------------------
    void Indicate(int r,int x)
    {
      SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
      RazrDisplay=g_registerArray[r];  // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
      digitalWrite(latchPin, LOW);  // устанавливаем синхронизацию "защелки" на LOW
      shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
      shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
      digitalWrite(latchPin, HIGH);  //"защелкиваем" регистр, тем самым устанавливая значения на выходах
    
      delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
    }
    
    Левая цифра мелькает в такт секунде. И еще не понятно из кода, где прописана нога 2, откуда считываются данные датчика ((
     
    Последнее редактирование: 25 ноя 2017
  7. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Я уже писал, что данный код реализует динамическую индикацию, причём реализует её через задницу. Здесь вообще всё надо переписывать.
     
  8. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    Ясно. бум искать )
     
  9. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    В данной ситуации (всего два разряда и два HC595) куда проще реализовать всё без динамической индикации вовсе - каждый разряд тупо повесить на свой 595ый.
    А динамическая индикация без прерываний и гарантированного задания интервалов - профанация самой идеи.
     
    Revenger нравится это.
  10. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    Конечно проще. И наверняка лучше.... Но ... в двух строках вашего поста столько страшных слов, что я вообще засомневался в целесообразности затеянного :)
    Поищу примеры, попробую на разные вывести.
     
  11. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    чота пока не нашёл, как двухразрядный индикатор с 10 выводами повесить раздельно на 559-е микросхемы...
     
  12. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    А, он единый, тогда да - только динамическая
     
  13. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    Я тут флпрог пытаюсь освоить (прошу тапками не кидаться, но когда модулями визуально представлено, мне как-то чуть проще),
    но не хватает ума самому решить как сделать запись в еепром до отключения питания автоматом.
    Может подскажет кто...
    Код:
    #include <Wire.h>
    #include  <SPI.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>
    LiquidCrystal_I2C _lcd1(0x27, 16, 2);
    int _dispTempLength1=0;
    boolean _isNeedClearDisp1;
    
    unsigned long _gtv1;
    bool _gtv2;
    unsigned long _gtv3 = 0;
    bool _trgrt2 = 0;
    bool _trgrt2I = 0;
    bool _SEEPR1OSN = 0;
    int _disp1oldLength = 0;
    int _disp4oldLength = 0;
    unsigned long _swi2;
    unsigned long _stou1 = 0UL;
    unsigned long _swi1;
    unsigned long _swi3;
    bool _bounseInputD4S = 0;
    bool _bounseInputD4O = 0;
    unsigned long _bounseInputD4P = 0UL;
    int _disp2oldLength = 0;
    unsigned long _SCT3 = 0UL;
    unsigned long _SCT3IC = 0UL;
    unsigned long _SCT3P = 0UL;
    int _SCT3_CPOP = 0;
    bool _SCT3_RCPIOS = 0;
    int _sido1TB = 0;
    String _sido1TSN;
    bool _sido1a1 = 0;
    bool _sido1b1 = 0;
    bool _sido1c1 = 0;
    bool _sido1d1 = 0;
    bool _sido1e1 = 0;
    bool _sido1f1 = 0;
    bool _sido1g1 = 0;
    bool _sido1dp = 0;
    bool _sido1r1 = 0;
    bool _sido1r2 = 0;
    int _sido1Raz = 1;
    unsigned long _sido1STi = 0UL;
    bool _sido1Mod = 0;
    unsigned long _stou2 = 0UL;
    int _disp3oldLength = 0;
    byte _74HC5951OB1 = 0;
    byte _74HC5951OB2 = 0;
    byte _74HC5951TB = 0;
    bool _74HC5951NS = 0;
    bool _trgrt1 = 0;
    bool _trgrt1I = 0;
    void setup()
    {
    Wire.begin();
    delay(10);
    Serial.begin(9600);
    pinMode(4, INPUT);
    digitalWrite(4, HIGH);
    
    _lcd1.init();
    _lcd1.backlight();
    _bounseInputD4O =  digitalRead(4);
    pinMode(3, INPUT);
    _SCT3P=micros();
    attachInterrupt(1, _SCT3coutFunction, FALLING);
    attachInterrupt(1, _SCT3positiveCoutFunction, RISING );
    SPI.begin();
    pinMode(10, OUTPUT);
    pinMode(8, OUTPUT);
    _stou2 = millis();
    _stou1 = millis();
    }
    void loop()
    {if (_isNeedClearDisp1) {_lcd1.clear(); _isNeedClearDisp1= 0;}
    
    bool  _bounceInputTmpD4 =  (digitalRead (4));
    
    if (_bounseInputD4S)
        {
         if (millis() >= (_bounseInputD4P + 40))
             {_bounseInputD4O= _bounceInputTmpD4; _bounseInputD4S=0;}
         }
    else
        {
         if (_bounceInputTmpD4 != _bounseInputD4O )
             {_bounseInputD4S=1; _bounseInputD4P = millis();}
          }
    
    
    
    
    //Плата:1
    //Наименование:Прием километрожа
    if (_bounseInputD4O) { if (_trgrt1I) { _trgrt1 = 0;} else {_trgrt1 = 1; _trgrt1I = 1;} } else {_trgrt1 = 0; _trgrt1I = 0;};
    if(_trgrt1){ if(!_SEEPR1OSN){(updateUnsignedLongToEEPROM(0, 0, 0x0, (_gtv1)));
    _SEEPR1OSN=1;} }else{ if(_SEEPR1OSN){_SEEPR1OSN=0;}}
    if((_SCT3_CPOP) == (6))
    {_swi3=(_gtv3)+(1UL);}
    else
    {_swi3=_gtv3;}
    if(_trgrt2)
    {_swi2=(readUnsignedLongFromEEPROM(0, 0, 0x0));}
    else
    {_swi2=_gtv1;}
    if (!(_bounseInputD4O)) { if (_trgrt2I) { _trgrt2 = 0;} else {_trgrt2 = 1; _trgrt2I = 1;} } else {_trgrt2 = 0; _trgrt2I = 0;};
    if((_SCT3_CPOP) == (6))
    {_swi1=(_swi2)+(1UL);}
    else
    {_swi1=_swi2;}
    if((( micros()-_SCT3P) >500000)||(( micros()-_SCT3P) <0)){_SCT3 = _SCT3IC;_SCT3IC=0;_SCT3P = micros();}
    if(_gtv2) {if ( !_SCT3_RCPIOS) {_SCT3_CPOP = 0; _SCT3_RCPIOS = 1;} } else {_SCT3_RCPIOS = 0;}
    if (1) {
    _dispTempLength1 = (String("\377")).length();
    if (_disp3oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
    _disp3oldLength = _dispTempLength1;
    _lcd1.setCursor(5, 0);
    _lcd1.print(String("\377"));
    } else {
    if (_disp3oldLength > 0) {_isNeedClearDisp1 = 1; _disp3oldLength = 0;}
    }
    _gtv3 = _swi3;
    if (1) {
    _dispTempLength1 = (String("\377")).length();
    if (_disp4oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
    _disp4oldLength = _dispTempLength1;
    _lcd1.setCursor(5, 1);
    _lcd1.print(String("\377"));
    } else {
    if (_disp4oldLength > 0) {_isNeedClearDisp1 = 1; _disp4oldLength = 0;}
    }
    if (1) {
    _dispTempLength1 = (((String(_swi3, DEC)))).length();
    if (_disp1oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
    _disp1oldLength = _dispTempLength1;
    _lcd1.setCursor(0, 0);
    _lcd1.print(((String(_swi3, DEC))));
    } else {
    if (_disp1oldLength > 0) {_isNeedClearDisp1 = 1; _disp1oldLength = 0;}
    }
    _gtv1 = _swi1;
    if (1) {
    _dispTempLength1 = (((String(_swi1, DEC)))).length();
    if (_disp2oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
    _disp2oldLength = _dispTempLength1;
    _lcd1.setCursor(0, 1);
    _lcd1.print(((String(_swi1, DEC))));
    } else {
    if (_disp2oldLength > 0) {_isNeedClearDisp1 = 1; _disp2oldLength = 0;}
    }
    _gtv2 = (_SCT3_CPOP) == (6);
    if (0){ if (_isTimer(_stou2, 1000 )) {Serial.print((readUnsignedLongFromEEPROM(0, 0, 0x0))); _stou2 = millis();}} else {_stou2 = millis();}
    
    //Плата:2
    //Наименование:Датчик уровня
    if(_isTimer(_sido1STi, 1 )) {
    _sido1STi = millis();
    if (_sido1Raz > 2) {_sido1Raz = 1;}
    if(_sido1Mod){
    _sido1a1 =1;
    _sido1b1 =1;
    _sido1c1 =1;
    _sido1d1 =1;
    _sido1e1 =1;
    _sido1f1 =1;
    _sido1g1 =1;
    _sido1r2 =0;
    _sido1r1 =0;
    _sido1Mod=0;} else {
    _sido1TSN = String ((map(( (analogRead (0))), (636), (924), (0), (30))));
    _sido1TB = _IntToSevenSegment(_charFromStringForIndex(_sido1TSN,_sido1Raz));
    _sido1a1 =! bitRead(_sido1TB, 0);
    _sido1b1 =! bitRead(_sido1TB, 1);
    _sido1c1 =! bitRead(_sido1TB, 2);
    _sido1d1 =! bitRead(_sido1TB, 3);
    _sido1e1 =! bitRead(_sido1TB, 4);
    _sido1f1 =! bitRead(_sido1TB, 5);
    _sido1g1 =! bitRead(_sido1TB, 6);
    _sido1r2 =  (_sido1Raz==1);
    _sido1r1 =  (_sido1Raz==2);
    if(_sido1Raz == 2) {_sido1dp = !  (0);}
    if(_sido1Raz == 1) {_sido1dp = !  (0);}
    _sido1Raz = _sido1Raz +1; _sido1Mod=1;} }
    _74HC5951NS = 0;
    bitWrite(_74HC5951TB, 0, _sido1a1);
    bitWrite(_74HC5951TB, 1, _sido1b1);
    bitWrite(_74HC5951TB, 2, _sido1c1);
    bitWrite(_74HC5951TB, 3, _sido1d1);
    bitWrite(_74HC5951TB, 4, _sido1e1);
    bitWrite(_74HC5951TB, 5, _sido1f1);
    bitWrite(_74HC5951TB, 6, _sido1g1);
    bitWrite(_74HC5951TB, 7, 0);
    if(! (_74HC5951TB == _74HC5951OB1)){_74HC5951OB1 = _74HC5951TB; _74HC5951NS = 1;}
    bitWrite(_74HC5951TB, 0, 0);
    bitWrite(_74HC5951TB, 1, _sido1r1);
    bitWrite(_74HC5951TB, 2, _sido1r2);
    bitWrite(_74HC5951TB, 3, 0);
    bitWrite(_74HC5951TB, 4, 0);
    bitWrite(_74HC5951TB, 5, 0);
    bitWrite(_74HC5951TB, 6, 0);
    bitWrite(_74HC5951TB, 7, 0);
    if(! (_74HC5951TB == _74HC5951OB2)){_74HC5951OB2 = _74HC5951TB; _74HC5951NS = 1;}
    if (_74HC5951NS) {
    digitalWrite(8, 0);
    SPI.transfer(_74HC5951OB2);
    SPI.transfer(_74HC5951OB1);
    digitalWrite(8, 1);}
    if (!(0)){ if (_isTimer(_stou1, 1000 )) {Serial.println( (analogRead (0))); _stou1 = millis();}} else {_stou1 = millis();}
    
    
    
    
    }
    bool _isTimer(unsigned long startTime, unsigned long period )
      {
      unsigned long currentTime;
    currentTime = millis();
    if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));}
      }
    void  _SCT3coutFunction()
    { _SCT3IC++;
    attachInterrupt(1, _SCT3positiveCoutFunction, RISING );
    }
    void  _SCT3positiveCoutFunction()
    { _SCT3_CPOP = _SCT3_CPOP +1;
    attachInterrupt(1, _SCT3coutFunction, FALLING  );
    }
    byte  _IntToSevenSegment(int value)
      {
    if (value==48) {return 63;}
    if (value==49) {return 6;}
    if (value==50) {return 91;}
    if (value==51) {return 79;}
    if (value==52) {return 102;}
    if (value==53) {return 109;}
    if (value==54) {return 125;}
    if (value==55) {return 7;}
    if (value==56) {return 127;}
    if (value==57) {return 111;}
    if (value==45) {return 64;}
    if (value==65) {return 119;}
    if (value==67) {return 57;}
    if (value==99) {return 88;}
    if (value==100) {return 94;}
    if (value==69) {return 121;}
    if (value==70) {return 113;}
    if (value==72) {return 118;}
    if (value==104) {return 116;}
    if (value==76) {return 56;}
    if (value==79) {return 63;}
    if (value==111) {return 92;}
    if (value==80) {return 115;}
    if (value==114) {return 80;}
    if (value==83) {return 109;}
    if (value==116) {return 120;}
    if (value==85) {return 62;}
    if (value==117) {return 28;}
    if (value==110) {return 84;}
    return 0;
      }
    int _charFromStringForIndex(String val, int idx)
    {int lengt=val.length();
      if(lengt < idx) return 0;
      return val.charAt(lengt-idx);
       }
    byte readByteFromEEPROM(int addres, byte bitAddres, byte chipAddres)
    {
    return EEPROM.read(addres);
    }
    void updateByteToEEPROM(int addres, byte bitAddres, byte chipAddres, byte value)
    {
    return EEPROM.update(addres, value);
    }
    unsigned long readUnsignedLongFromEEPROM(int addres, byte bitAddres, byte chipAddres)
    {
    byte x[4];
    for(byte i = 0; i < 4; i++) { x[i] = readByteFromEEPROM( (addres+i),  bitAddres,  chipAddres);}
    unsigned long *y = (unsigned long *)&x;
    return y[0];
    }
    void updateUnsignedLongToEEPROM(int addres, byte bitAddres, byte chipAddres, unsigned long value)
    {
    byte *x = (byte *)&value;
    for(byte i = 0; i < 4; i++) {updateByteToEEPROM( (addres+i),  bitAddres,  chipAddres, x[i]);}
    }
    Здесь в основном код одного коллеги, я лиш добавил дисплей, алгоритм таков - включили ардуино, пин 4 на минус (типа включили зажигание), счётчик считает, отключили пин4 - запись в еепром, а первый счётчик после перезагрузки обнуляется.

    Здесь индикаторы после комента "плата 2" от прежнего кода, я его забыл удалить. Добавил вывод на дисплей 16х2 в одну строку "дневной пробег", и во вторую "постоянный", вот постоянный, если не отключать пин 4 от минуса и перегрузить ардуину - не сохраняется, а если отключить пин 4 и перегрузить ардуину не подключив - обнуляется и еепром.

    п.с. сейчас проверил, если не отключая ардуино передёргуть пин 4, что после перезагрузки данные сохранены. Надо сделать какой-то автовключатель пина раз в какое-то время может быть?
     
    Последнее редактирование: 26 ноя 2017
  14. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Я вообще не понимаю код - там вокруг элементарной задачи столько всего накручено, что разбираться в этом спагетти-коде мне тупо лень. Особенно учитывая ноль комментариев и любовь к одинаковым именам, отличающимся одной буквой.
    Обычная ошибка в логике - обработка состояния пина 4 проверяется до считывания EEPROM, в результате запись идёт до чтения. Но понять логику кода я не в состоянии.
     
    Revenger нравится это.
  15. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    Да, этот код сотворила программа , отсюда и мешанина. Но он работает, как ни странно. Не тот код, что в предыдущем посте, а вообще, то, что я за ночь сумел набросать.
    Для программистов это конечно жесть и наверное (модное слово) моветон, а для дилетанта как я - спасение какое-никакое.
    В итоге мучений и попыток понять в чём отличие счётчика или функции сравнения, получил код, который мне нужен.
    В данном случае это счётчик суточного и дневного пробега (только параметр пока счёта в метрах), с записью в епром, а так же сброс кнопкой суточного пробега.

    Может кому-то интересно будет, вот код:
    Код:
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>
    LiquidCrystal_I2C _lcd1(0x27, 16, 2);
    int _dispTempLength1=0;
    boolean _isNeedClearDisp1;
    
    bool _gtv1;
    int _gtv3;
    bool _count1I = 0;
    int _count1P = 0;
    bool _count3I = 0;
    int _count3P = 0;
    bool _SEEPR1OSN = 0;
    int _disp2oldLength = 0;
    bool _bounseInputD2S = 0;
    bool _bounseInputD2O = 0;
    unsigned long _bounseInputD2P = 0UL;
    bool _trgrt2 = 0;
    bool _trgrt2I = 0;
    bool _SEEPR2OSN = 0;
    bool _trgrt1 = 0;
    bool _trgrt1I = 0;
    unsigned long _SCT3 = 0UL;
    unsigned long _SCT3IC = 0UL;
    unsigned long _SCT3P = 0UL;
    int _SCT3_CPOP = 0;
    bool _SCT3_RCPIOS = 0;
    bool _trgrt4 = 0;
    bool _trgrt4I = 0;
    int _disp1oldLength = 0;
    void setup()
    {
    Wire.begin();
    delay(10);
    pinMode(2, INPUT);
    digitalWrite(2, HIGH);
    
    _lcd1.init();
    _lcd1.backlight();
    _bounseInputD2O =  digitalRead(2);
    pinMode(3, INPUT);
    _SCT3P=micros();
    attachInterrupt(1, _SCT3coutFunction, FALLING);
    attachInterrupt(1, _SCT3positiveCoutFunction, RISING );
    }
    void loop()
    {if (_isNeedClearDisp1) {_lcd1.clear(); _isNeedClearDisp1= 0;}
    
    bool  _bounceInputTmpD2 =  (digitalRead (2));
    
    if (_bounseInputD2S)
        {
         if (millis() >= (_bounseInputD2P + 40))
             {_bounseInputD2O= _bounceInputTmpD2; _bounseInputD2S=0;}
         }
    else
        {
         if (_bounceInputTmpD2 != _bounseInputD2O )
             {_bounseInputD2S=1; _bounseInputD2P = millis();}
          }
    
    
    
    
    //Плата:1
    if((( micros()-_SCT3P) >500000)||(( micros()-_SCT3P) <0)){_SCT3 = _SCT3IC;_SCT3IC=0;_SCT3P = micros();}
    if(_gtv1) {if ( !_SCT3_RCPIOS) {_SCT3_CPOP = 0; _SCT3_RCPIOS = 1;} } else {_SCT3_RCPIOS = 0;}
    if(_trgrt1) _count1P = ((readIntegerFromEEPROM(2, 0, 0x0)));
    if ((_SCT3_CPOP) == (6))
       {
       if (! _count1I)
          {
           _count1P = _count1P+1;
           _count1I = 1;
          }
       }
    else
       {
       _count1I=0;
       }
    if (!(_bounseInputD2O)) _count1P = 0;
    if (1) { if (_trgrt1I) { _trgrt1 = 0;} else {_trgrt1 = 1; _trgrt1I = 1;} } else {_trgrt1 = 0; _trgrt1I = 0;};
    if(_trgrt2){ if(!_SEEPR1OSN){(updateIntegerToEEPROM(2, 0, 0x0, (_count1P)));
    _SEEPR1OSN=1;} }else{ if(_SEEPR1OSN){_SEEPR1OSN=0;}}
    if(_trgrt4) _count3P = ((readIntegerFromEEPROM(0, 0, 0x0)));
    if ((_SCT3_CPOP) == (6))
       {
       if (! _count3I)
          {
           _count3P = _count3P+1;
           _count3I = 1;
          }
       }
    else
       {
       _count3I=0;
       }
    if (1) { if (_trgrt4I) { _trgrt4 = 0;} else {_trgrt4 = 1; _trgrt4I = 1;} } else {_trgrt4 = 0; _trgrt4I = 0;};
    if(_trgrt2){ if(!_SEEPR2OSN){(updateIntegerToEEPROM(0, 0, 0x0, (_count3P)));
    _SEEPR2OSN=1;} }else{ if(_SEEPR2OSN){_SEEPR2OSN=0;}}
    if (( (analogRead (2))) <= (400)) { if (_trgrt2I) { _trgrt2 = 0;} else {_trgrt2 = 1; _trgrt2I = 1;} } else {_trgrt2 = 0; _trgrt2I = 0;};
    if (1) {
    _dispTempLength1 = ((((String("days   ")) + ((String(_count1P, DEC)))))).length();
    if (_disp1oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
    _disp1oldLength = _dispTempLength1;
    _lcd1.setCursor(0, 0);
    _lcd1.print((((String("days   ")) + ((String(_count1P, DEC))))));
    } else {
    if (_disp1oldLength > 0) {_isNeedClearDisp1 = 1; _disp1oldLength = 0;}
    }
    _gtv3 = _count1P;
    _gtv1 = (_SCT3_CPOP) == (6);
    if (1) {
    _dispTempLength1 = ((((String("total  ")) + ((String(_count3P, DEC)))))).length();
    if (_disp2oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
    _disp2oldLength = _dispTempLength1;
    _lcd1.setCursor(0, 1);
    _lcd1.print((((String("total  ")) + ((String(_count3P, DEC))))));
    } else {
    if (_disp2oldLength > 0) {_isNeedClearDisp1 = 1; _disp2oldLength = 0;}
    }
    
    
    
    
    }
    void  _SCT3coutFunction()
    { _SCT3IC++;
    attachInterrupt(1, _SCT3positiveCoutFunction, RISING );
    }
    void  _SCT3positiveCoutFunction()
    { _SCT3_CPOP = _SCT3_CPOP +1;
    attachInterrupt(1, _SCT3coutFunction, FALLING  );
    }
    byte readByteFromEEPROM(int addres, byte bitAddres, byte chipAddres)
    {
    return EEPROM.read(addres);
    }
    void updateByteToEEPROM(int addres, byte bitAddres, byte chipAddres, byte value)
    {
    return EEPROM.update(addres, value);
    }
    int readIntegerFromEEPROM(int addres, byte bitAddres, byte chipAddres)
    {
    byte hight = readByteFromEEPROM( addres,  bitAddres,  chipAddres);
    byte low = readByteFromEEPROM( (addres+1),  bitAddres,  chipAddres);
    return  word(hight, low);
    }
    void updateIntegerToEEPROM(int addres, byte bitAddres, byte chipAddres, int value)
    {
    updateByteToEEPROM( addres,  bitAddres,  chipAddres, highByte(value));
    updateByteToEEPROM( (addres+1),  bitAddres,  chipAddres, lowByte(value));
    }
    Подключение ардуино:
    А2 - пин определения наличия питания (с делителя по 5кОм)
    пин2 - пин сброса суточного пробега
    дисплей подключен по i2c
    питание ардуины, через диод и конденсаторы на 3300мкФ, этого хватает, чтобы сохранилось в память при выключении питания (заказал ионистр на будущее)

    Его я попытаюсь связать с уровнем топлива, код, который с вашей помощью сделал ранее, но если индикатор будет мерцать (судя по всему это неизбежно), то или дисплей буду покупать графический, или отдельную ардуинку пущу на индикаторы, отдельную на остальное.
    А может, как мне посоветовали, вообще сделаю приложение на андроид, куда будут передаваться мои данные (и не нужны ни индикаторы ни дисплеи). Собрался ехать - прилепил телефон ненужный вместо панели, и вот тебе все датчики )))
    [​IMG]
     
  16. LampGraph

    LampGraph Кандидат наук

    Регистрация:
    16 ноя 2015
    Сообщения:
    1.229
    Город:
    Абакан
    Имя:
    Вячеслав
    Совершенно точно, что-то я как с 1С заморочился так тупить стал.
     
  17. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    Ну это ничего ))
    Тем временем код у меня уже почти сделан и осталось прилепить тахометр. Пока ищу информацию как считывать импульсы с датчика индуктивности (при вращении вала на его контактах около 3в, проверял светодиодом).
    Пока код содержит функцию отображения уровня топлива, скорости и вывод на экран пробега, с сохранением в еепром.
     
  18. Marksheider

    Marksheider Научный сотрудник

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Приехали ко мне датчики хола для ардуино. пробую с помощью их мерить обороты, вроде даже работает все. Датчик реагирует на поле магнитов расположенных в стакане мотора.
    Посчитал количество полюсов на которое срабатывает датчик, для мотора Gartt 5010 300kv получилось 8 полюсов. Вернее датчие срабатывает на 8 магнитов.
    В общем почему то различается частота на одном и том же моторе посчитанная оптическим датчиком и датчиком хола. хол ее занижает почему то. Думаю что в математике проблема но в чем именно???
    PC230234.JPG
     
  19. Revenger

    Revenger Старший научный сотрудник

    Регистрация:
    10 ноя 2016
    Сообщения:
    912
    Город:
    Ставрополь
    Имя:
    Александр
    ну а как в программе задано? Для оптического одна метка, а для холла 8 магнитов.
     
  20. Marksheider

    Marksheider Научный сотрудник

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Просто делю на 8 получаемый сигнал.
    --- Сообщения объединены, 23 дек 2017 ---
    В общем сам обсчитался. посмотрел параметры мотора, у него 14 магнитов в колоколе вклеено. датчик холла получается реагирует на 7 из них.
    Щас вот взял поменял на 7 и все встало на свои места. Только последние два знака скачат на датчике хола. на оптическом стоят как вкопанные.
    PC230235.JPG
     
  21. An_private

    An_private Старший научный сотрудник

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    14 магнитов в разной полярности, поэтому перемена полярности поля на холле происходит 7 раз.
    Фильтрация на результат счёта холла сделана так же?
     
Реклама. Купить это место.