РЕШЕНО Hx711 не работает без usb.

Тема в разделе "Arduino & Shields", создана пользователем LeTaGa, 4 окт 2020.

Метки:
  1. LeTaGa

    LeTaGa Нерд

    Здравствуйте. 2 года назад собрал прибор для измерения тяги модели ракетного двигателя. Ничего нового не изобретал: HX711, arduino nano, micro Sd card. Прибор регулярно простаивал(бывало по пол года) но работу свою делал, без ошибок. Однако недавно начались проблемы(после 4 месяцев простоя), без USB от ПК, записывалась каша, при этом стоит "на горячую" подключить к пк, так становится все нормально. Так же если выключить ардуино в диспетчере устройств(или удалить драйвер) тоже начиналась писаться каша. Как это решать, я не знаю. Пробовал ставить фильтры в питание, испольнозавать телефон в качестве Serial порта, ничего не помогает. Прошу помочь. Вот код программы:
    Код (C++):
    #include "HX711.h" // для датчика
    #include <SPI.h> // для карты памяти
    #include <SD.h> // для карты памяти
    #include <EEPROM.h> // для номерации эксперементов.

    const int button = 7;
    const int LCD_RED = 5;
    const int LCD_BLUE = 6;
    const int START = 4;
    const uint8_t PIN_CS = 10;                         // указываем номер вывода arduino подключенного к выводу CS адаптера
    const int time_one = 10;
    long ad0 = 0;
    long ad1 = 0;
    long ad2 = 0;
    boolean  control = 0;
    float ad3;
    int x  = 0;
    int y = 0;
    int z = 0;
    int p = 0;
    File myFile; // Для работы с файлами
    HX711 scale(A1, A0); // Указываем ввыводы с датчиком
    float calibration_factor;          // калибровка!
    float units; // датчик
    float ounces; // датчик


    void setup() {
      delay(10000);
      pinMode(LCD_RED, OUTPUT); // инициализация ввыводов ардуино
      pinMode(LCD_BLUE, OUTPUT); // инициализация ввыводов ардуино
      pinMode(START, INPUT); // инициализация ввыводов ардуино
      pinMode(button, INPUT); // инициализация ввыводов ардуино
      digitalWrite(button, HIGH); //Устанавливаем подтяжку для кнопки
      scale.set_scale();
      scale.tare();                              //Сбрасываем на 0
      scale.set_scale();
      //scale.set_scale(125.2);
      while (!Serial) {
        ; // ожидаем соединение последовательного порта
      }
       if (!SD.begin(PIN_CS)) {
        while(1){
            digitalWrite(LCD_RED, HIGH); // ошибка
           delay(200);
           digitalWrite(LCD_RED, LOW);
            delay(200);
        }
      }
       for(int h = 0; h<=5; h++){ // мигаем светодиодом
           digitalWrite(LCD_BLUE, HIGH);
           delay(50);
            digitalWrite(LCD_BLUE, LOW);
            delay(50);
      }

    }

    void loop() {
      if(digitalRead(button) != 1){
        delay(10);
        if(digitalRead(button) != 1){
          ad0 = millis();
          while(1){
            digitalWrite(LCD_RED, HIGH);
            if(digitalRead(button) != 0){
              delay(10);
              if(digitalRead(button) != 0){
                ad1 = millis();
                digitalWrite(LCD_RED, LOW);
                break;
              }
            }
          }
         
          if((ad1-ad0) > 2000){
            setting();
          }
          else{
            XP();
          }
        }
      }
    }





    void XP(){
      digitalWrite(LCD_BLUE, HIGH); // подаем сигнал о начале эксперемента
       while(1){
        if(digitalRead(START) == 1){
          delay(10);
          if(digitalRead(START) == 1){
            break;
          }
        }
        }
      digitalWrite(LCD_BLUE, LOW); // даём сигнал об окончании отсчета
      myFile = SD.open("EXP.txt", FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
       if(!myFile){ // Проверяем открыт ли файл.
          while(1){
              delay(200);          // файл не открыт
              digitalWrite(LCD_RED, HIGH);
              delay(200);
              digitalWrite(LCD_RED, LOW);          
             }
         }
     
       myFile.println(""); // Отступаем от прошлых записей.
       myFile.print("Experiment"); // пишем эксперемент.
       myFile.print(EEPROM.read(0)); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
       myFile.println("");// Отступаем от прошлых записей.
       EEPROM.write(0, (EEPROM.read(0) + 1)); // прибавляем 1 к номеру эксперемента.
       digitalWrite(LCD_RED, HIGH); // даем сигнал о начале записи
      //  units = scale.get_units(), 10;
       //digitalWrite(START, HIGH); // Даем сигнал на запуск эксперемента
       ad0 = millis(); // записываем время начало эксперемента
       myFile.println("");
       myFile.print(" ");
       myFile.print(ad0); // записываем время
       myFile.println("");
       while(1){
         units = scale.get_units(), 10; // Считываем показания датчика.
         ad2 = millis(); // записываем окончания считывания
         myFile.print(units); // записываем показания
         myFile.print(" ");
         ad3 = (ad2-ad0)/1000.00;
         myFile.println(ad3); // записываем время
        //if((ad2 - ad0) >= 10000){ //
        //  digitalWrite(START, LOW);
        //}
        if(digitalRead(button) != 1){ // нажата ли кнопка?
          delay(10);
          if(digitalRead(button) != 1){
            myFile.println("End to Experiment");
            myFile.close();
            while(1){
              digitalWrite(LCD_BLUE, HIGH);
              digitalWrite(LCD_RED, LOW);
              delay(100);
              digitalWrite(LCD_BLUE, LOW);
              digitalWrite(LCD_RED, HIGH);
              delay(100);
            }
          }
        }
        delay(100);
       }
    }












    void setting(){
      if(SD.exists("EXP.txt")){
        SD.remove("EXP.txt");
      }
      myFile = SD.open("EXP.txt", FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
      if(!myFile){ // Проверяем открыт ли файл.
       while(1){
         delay(200);        
         digitalWrite(LCD_RED, HIGH);
         delay(200);
         digitalWrite(LCD_RED, LOW);
       }
      }                
     myFile.println(""); // Отступаем от прошлых записей.
     myFile.print("calibration_smartPhone "); // пишем эксперемент.
     myFile.print(EEPROM.read(0)); myFile.print(": "); // Даем ему номер. ( на карте их могут быть несколько, и в  них надо как-то орентироваться)
     units = scale.get_units(), 10; // Считываем показания датчика.
     ounces = units/141.8;
     myFile.println(ounces);
     myFile.println();
     myFile.println(units);
     units = scale.get_units(), 10;
     units = units / ounces;
    myFile.println();
    myFile.println(units);
    myFile.close();
    control = 0;
    for(int n = 0;n<=9;n++){
      units = scale.get_units(), 10;
      if(((units / ounces)<=130) || ((units / ounces)>=150)){
        control = 1;
        break;
      }
       delay(100);
    }
    if(control == 1){
         for(int y = 0;y<=5;y++){
         delay(500);        
         digitalWrite(LCD_RED, HIGH);
         delay(500);
         digitalWrite(LCD_RED, LOW);
         }
      }
    else{
         for(int y = 0;y<=5;y++){
         digitalWrite(LCD_BLUE, HIGH);
         delay(500);
         digitalWrite(LCD_BLUE, LOW);
         delay(500);
         }
      }
    }
     
  2. Airbus

    Airbus Радиохулиган Модератор

    Может sd карта деградирует? Если заменить?
     
  3. LeTaGa

    LeTaGa Нерд

    Возможно, но данные пишутся структурировано, показатели веса космические.
     
    Последнее редактирование: 4 окт 2020
  4. ZAZ-965

    ZAZ-965 Гуру

    @LeTaGa, а зачем вы ожидаете соединение по последовательному порту, если в дальнейшем его не используете?
    По моему, эта запись нужна для Arduino Leonardo, попробуйте закомментировать ее.
    Код (C++):
      while (!Serial) {
        ; // ожидаем соединение последовательного порта
      }
     
  5. Nekto_nikto

    Nekto_nikto Гик

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

    LeTaGa Нерд

    Да в том то и дело что с питание все нормально. Проблемы начинаются если нет соединения с ПК, т.е. если подключить к выключенному пк, удалить драйвер на ардуино или просто выключить его в диспетчере устройств. Питания там податься напрямую в 5в, автономно питается от литевого аккумулятора на 12в, через крену на 5в. Пробовал питать через USB(подключал к повер банку, и заряднику) не помогло.
     
  7. LeTaGa

    LeTaGa Нерд

    РЕШЕНИЕ. Проблему решил. Если в крации, дело в hx711. Разобрал устройство, и тыкнул мультиметром на линию 5в, при подключении USB от пк, на линии было 4.6в, потом отключил ардуино в диспетчере устройств, и напряжение поднялось до 4.8в ( в этот момент и начинаются глюки). Подключил ЛБП к линии 5в, и стал понижать напряжение, все завелось на напряжении 4.5в, потом организовал отдельное питание 4.5в для HX711 (все остальное питал от 5в), и все заработало как надо. Позже заменю HX711, и отпишусь, устранился ли дефект.
     
  8. sslobodyan

    sslobodyan Гик

    Проблема может быть в аналоговом питании. Чип по аналоговому питанию можно запитать напрямую от цифрового, а можно через его собственный регулятор (добавляется транзистор, два резистора и конденсатор). Соотв, эти элементы могут сбоить, а вы будете грешить на чип. Гляньте в ДШ чипа.
     
  9. Klaus_Fuks

    Klaus_Fuks Нуб

    Приветствую всех! Подскажите, пожалуйста, как правильно подключить тактовую кнопку и светодиоды, чтобы программа, которая в первом сообщении топика, работала. Тоже собираю в настоящее время стенд для проверки тяги модельных двигателей на основе Искры Нано. Но, подключив все компоненты (HX711, модуль SD, тактовую кнопку и два светодиода), программа не работает, светодиоды на включение контроллера никак не реагируют, равно как и на нажатие кнопки. Моих мозгов пока не хватает ( Буду очень благодарен!
     
    Последнее редактирование: 4 авг 2021
  10. Un_ka

    Un_ka Гуру

    ДВС или БКД?
    Схему подключения покажите.
     
  11. Klaus_Fuks

    Klaus_Fuks Нуб

    Двигатели ракетные твердотопливные.

    Контакты модуля HX711 DT и SCK подключены к пинам A1 и А0 соответственно.
    Контакты модуля карты памяти: MISO - пин 12, MOSI - пин 11, SCK - пин 13, CS - пин 10.
    Светодиоды синий и крысный: минус обоих светодиодов подлючен к земле, плюс синего - пин 6, плюс красного - пин 5.
    Тактовая кнопка: контакты подтягивающего напряжения (замкнуты на кнопке) - один на пин 7, второй через резистор 10 кОм к земле, третий контакт с кнопки (замыкается при нажатии) - на пин 4.

    Где я накосячил? ( Прошу сильно ногами не пинать. Только начинаю разбираться в этом.
     
    Последнее редактирование: 4 авг 2021
  12. Klaus_Fuks

    Klaus_Fuks Нуб

    Сделал схему подключения во фритце для наглядности. Точнее, так, как я подключил.
     

    Вложения:

    • Stend.jpg
      Stend.jpg
      Размер файла:
      395,3 КБ
      Просмотров:
      157
  13. Un_ka

    Un_ka Гуру

    У кнопки 4 контакта, они соединены попарно.
    Мне кажется в этом что-то не так.
    Может не работает из-за этого?
     
  14. LeTaGa

    LeTaGa Нерд

    Здравствуйте. Прошу прощения за задержку. На этом форуме я редкий гость). Светодиоды у вас не загораются из-за неправильного подключения. Плюсовые выводы нужно ввести к пинам D6 и D5.

    Кнопку нужно подключить так, чтоб она замыкала пин D7 на GND, подтяжку делать не нужно, т.к. она подключается внутри ардуино. Пин D4 это вход для пиротехнического пульта. Все остальное у вас вроде как правильно. Схема оригинала:[​IMG]

    У модуля HX711 есть 2-е скорости обновления данных. 10Гц и 80 Гц. Отрывок их даташита:
    [​IMG]

    Так же модуль достаточно капризный к питанию(возможно мне так повезло, и это только у меня), ему нужно напряжение 4.6в. Со временем нужное напряжение может начать “гулять”, поэтому вам потребуется мини ЛБП, для питания схемы. Так же этот модуль начинает менять показания в зависимости от температуры, из-за чего запись данных сразу в ньютонах невозможна, данные нужно обрабатывать после записи в Excel.

    Большинство дешёвых датчиков не могут работать при температурах ниже -5г. Если планируются испытания на сильном морозе, то следует продумать теплоизоляцию, и подогрев.

    Шлейф от датчика нужно скрутить в косичку для уменьшения помех.

    Далее руководство по эксплуатации.

    Программа имеет 2 режима работы, это настройка и запись.

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

    Настройка активируется при зажатии кнопки больше 2сек. При этом на датчик нужно положить груз с заранее известной массой(её необходимо указать в программе), по умолчанию там 141.8г. Если на карте памяти будет файл с данными, то он удалится, и будет создан новый. Далее в новый файл будут записаны данные калибровки. После будет включён режим теста, программа будет получать записи, и сравнивать их с первой записью, если изменения в пределах +-10г, то будет мигать светодиод на пине D6, а если нет, то светодиод на пине D5. При повторном нажатии кнопки, программа выйдет из режима настройки.

    Теперь как обработать данные.

    Открываем таблицу в Excel, запихиваем туда данные, после чего берём вес двигателя (в ньютонах), до его запуска, и просто делим первую запись на вес двигателя. Далее делим на получившееся число все остальные записи. При испытаниях в сильный мороз, показания будут гулять, поэтому проделывать это нужно с несколькими записями, и смотреть где отклонения меньше. Данные калибровки из режима настройки дадут показания в граммах, можно использовать для проверки работоспособности (индикатор переохлаждения датчика).
     
  15. LeTaGa

    LeTaGa Нерд

    Код (C++):
    #include "HX711.h" // для датчика
    #include <SPI.h> // для карты памяти
    #include <SD.h> // для карты памяти
    #include <EEPROM.h> // для номерации эксперементов.

    const int button = 7;
    const int LCD_RED = 5;
    const int LCD_BLUE = 6;
    const int START = 4;
    const uint8_t PIN_CS = 10;                         // указываем номер вывода arduino подключенного к выводу CS адаптера
    const int time_one = 10;
    long ad0 = 0;
    long ad1 = 0;
    long ad2 = 0;
    boolean  control = 0;
    float ad3;
    float conf = 141.8; //масса груза
    int x  = 0;
    int y = 0;
    int z = 0;
    int p = 0;
    File myFile; // Для работы с файлами
    HX711 scale(A1, A0); // Указываем ввыводы с датчиком
    float calibration_factor;          // калибровка!
    float units; // датчик
    float ounces; // датчик


    void setup() {
      //delay(10000);
      pinMode(LCD_RED, OUTPUT); // инициализация ввыводов ардуино
      pinMode(LCD_BLUE, OUTPUT); // инициализация ввыводов ардуино
      pinMode(START, INPUT); // инициализация ввыводов ардуино
      pinMode(button, INPUT); // инициализация ввыводов ардуино
      digitalWrite(button, HIGH); //Устанавливаем подтяжку для кнопки
      scale.set_scale();
      scale.tare();                              //Сбрасываем на 0
      scale.set_scale();
      //scale.set_scale(125.2);
      while (!Serial) {
        ; // ожидаем соединение последовательного порта
      }
       if (!SD.begin(PIN_CS)) {
        while(1){
            digitalWrite(LCD_RED, HIGH);
           delay(200);
           digitalWrite(LCD_RED, LOW);
            delay(200);
        }
      }
       for(int h = 0; h<=5; h++){ // мигаем светодиодом
           digitalWrite(LCD_BLUE, HIGH);
           delay(50);
            digitalWrite(LCD_BLUE, LOW);
            delay(50);
      }

    }

    void loop() {
      if(digitalRead(button) != 1){
        delay(10);
        if(digitalRead(button) != 1){
          ad0 = millis();
          while(1){
            digitalWrite(LCD_RED, HIGH);
            if(digitalRead(button) != 0){
              delay(10);
              if(digitalRead(button) != 0){
                ad1 = millis();
                digitalWrite(LCD_RED, LOW);
                break;
              }
            }
          }
         
          if((ad1-ad0) > 2000){
            setting();
          }
          else{
            XP();
          }
        }
      }
    }





    void XP(){
      digitalWrite(LCD_BLUE, HIGH); // подаем сигнал о начале эксперемента
       while(1){
        if(digitalRead(START) == 1){
          delay(10);
          if(digitalRead(START) == 1){
            break;
          }
        }
        }
      digitalWrite(LCD_BLUE, LOW); // даём сигнал об окончании отсчета
      myFile = SD.open("EXP.txt", FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
       if(!myFile){ // Проверяем открыт ли файл.
          while(1){
              delay(200);          // файл не открыт
              digitalWrite(LCD_RED, HIGH);
              delay(200);
              digitalWrite(LCD_RED, LOW);          
             }
         }
     
       myFile.println(""); // Отступаем от прошлых записей.
       myFile.print("Experiment"); // пишем эксперемент.
       myFile.print(EEPROM.read(0)); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
       myFile.println("");// Отступаем от прошлых записей.
       EEPROM.write(0, (EEPROM.read(0) + 1)); // прибавляем 1 к номеру эксперемента.
       digitalWrite(LCD_RED, HIGH); // даем сигнал о начале записи
      //  units = scale.get_units(), 10;
       //digitalWrite(START, HIGH); // Даем сигнал на запуск эксперемента
       ad0 = millis(); // записываем время начало эксперемента
       myFile.println("");
       myFile.print(" ");
       myFile.print(ad0); // записываем время
       myFile.println("");
       while(1){
         units = scale.get_units(), 10; // Считываем показания датчика.
         ad2 = millis(); // записываем окончания считывания
         myFile.print(units); // записываем показания
         myFile.print(" ");
         ad3 = (ad2-ad0)/1000.00;
         myFile.println(ad3); // записываем время
        //if((ad2 - ad0) >= 10000){ //
        //  digitalWrite(START, LOW);
        //}
        if(digitalRead(button) != 1){ // нажата ли кнопка?
          delay(10);
          if(digitalRead(button) != 1){
            myFile.println("End to Experiment");
            myFile.close();
            while(1){
              digitalWrite(LCD_BLUE, HIGH);
              digitalWrite(LCD_RED, LOW);
              delay(100);
              digitalWrite(LCD_BLUE, LOW);
              digitalWrite(LCD_RED, HIGH);
              delay(100);
            }
          }
        }
       // delay(100);
       }
    }












    void setting(){
      if(SD.exists("EXP.txt")){
        SD.remove("EXP.txt");
      }
      myFile = SD.open("EXP.txt", FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
      if(!myFile){ // Проверяем открыт ли файл.
       while(1){
         delay(200);        
         digitalWrite(LCD_RED, HIGH);
         delay(200);
         digitalWrite(LCD_RED, LOW);
       }
      }                
    myFile.println(""); // Отступаем от прошлых записей.
    myFile.print("calibration_smartPhone "); // пишем эксперемент.
    myFile.print(EEPROM.read(0)); myFile.print(": "); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
    units = scale.get_units(), 10; // Считываем показания датчика.
    ounces = units/conf;
    myFile.println(ounces);
    myFile.println();
    myFile.println(units);
    units = scale.get_units(), 10;
    units = units / ounces;
    myFile.println();
    myFile.println(units);
    myFile.close();
      while(1){
      units = scale.get_units(), 10;
      if(((units / ounces)<=(conf-10)) || ((units / ounces)>=(conf+10))){
         delay(250);        
         digitalWrite(LCD_RED, HIGH);
         delay(250);
         digitalWrite(LCD_RED, LOW);
      }
      else{
        digitalWrite(LCD_BLUE, HIGH);
         delay(250);
         digitalWrite(LCD_BLUE, LOW);
         delay(250);
    }
      if(digitalRead(button) != 1){
        delay(100);
        if(digitalRead(button) != 1){
          break;
        }
      }
      }
    }