Здравствуйте. 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); } } }
@LeTaGa, а зачем вы ожидаете соединение по последовательному порту, если в дальнейшем его не используете? По моему, эта запись нужна для Arduino Leonardo, попробуйте закомментировать ее. Код (C++): while (!Serial) { ; // ожидаем соединение последовательного порта }
Скорее всего у вас на ардуине сгорел стабилизатор напряжения на входе и поэтому когда вы подключаете к ПК у вас все работает как надо, а без него дуркует. Если в у вас там использована ардуина, попробуйте заменить на анлогичную, если есть в наличии.
Да в том то и дело что с питание все нормально. Проблемы начинаются если нет соединения с ПК, т.е. если подключить к выключенному пк, удалить драйвер на ардуино или просто выключить его в диспетчере устройств. Питания там податься напрямую в 5в, автономно питается от литевого аккумулятора на 12в, через крену на 5в. Пробовал питать через USB(подключал к повер банку, и заряднику) не помогло.
РЕШЕНИЕ. Проблему решил. Если в крации, дело в hx711. Разобрал устройство, и тыкнул мультиметром на линию 5в, при подключении USB от пк, на линии было 4.6в, потом отключил ардуино в диспетчере устройств, и напряжение поднялось до 4.8в ( в этот момент и начинаются глюки). Подключил ЛБП к линии 5в, и стал понижать напряжение, все завелось на напряжении 4.5в, потом организовал отдельное питание 4.5в для HX711 (все остальное питал от 5в), и все заработало как надо. Позже заменю HX711, и отпишусь, устранился ли дефект.
Проблема может быть в аналоговом питании. Чип по аналоговому питанию можно запитать напрямую от цифрового, а можно через его собственный регулятор (добавляется транзистор, два резистора и конденсатор). Соотв, эти элементы могут сбоить, а вы будете грешить на чип. Гляньте в ДШ чипа.
Приветствую всех! Подскажите, пожалуйста, как правильно подключить тактовую кнопку и светодиоды, чтобы программа, которая в первом сообщении топика, работала. Тоже собираю в настоящее время стенд для проверки тяги модельных двигателей на основе Искры Нано. Но, подключив все компоненты (HX711, модуль SD, тактовую кнопку и два светодиода), программа не работает, светодиоды на включение контроллера никак не реагируют, равно как и на нажатие кнопки. Моих мозгов пока не хватает ( Буду очень благодарен!
Двигатели ракетные твердотопливные. Контакты модуля HX711 DT и SCK подключены к пинам A1 и А0 соответственно. Контакты модуля карты памяти: MISO - пин 12, MOSI - пин 11, SCK - пин 13, CS - пин 10. Светодиоды синий и крысный: минус обоих светодиодов подлючен к земле, плюс синего - пин 6, плюс красного - пин 5. Тактовая кнопка: контакты подтягивающего напряжения (замкнуты на кнопке) - один на пин 7, второй через резистор 10 кОм к земле, третий контакт с кнопки (замыкается при нажатии) - на пин 4. Где я накосячил? ( Прошу сильно ногами не пинать. Только начинаю разбираться в этом.
У кнопки 4 контакта, они соединены попарно. Мне кажется в этом что-то не так. Может не работает из-за этого?
Здравствуйте. Прошу прощения за задержку. На этом форуме я редкий гость). Светодиоды у вас не загораются из-за неправильного подключения. Плюсовые выводы нужно ввести к пинам D6 и D5. Кнопку нужно подключить так, чтоб она замыкала пин D7 на GND, подтяжку делать не нужно, т.к. она подключается внутри ардуино. Пин D4 это вход для пиротехнического пульта. Все остальное у вас вроде как правильно. Схема оригинала: У модуля HX711 есть 2-е скорости обновления данных. 10Гц и 80 Гц. Отрывок их даташита: Так же модуль достаточно капризный к питанию(возможно мне так повезло, и это только у меня), ему нужно напряжение 4.6в. Со временем нужное напряжение может начать “гулять”, поэтому вам потребуется мини ЛБП, для питания схемы. Так же этот модуль начинает менять показания в зависимости от температуры, из-за чего запись данных сразу в ньютонах невозможна, данные нужно обрабатывать после записи в Excel. Большинство дешёвых датчиков не могут работать при температурах ниже -5г. Если планируются испытания на сильном морозе, то следует продумать теплоизоляцию, и подогрев. Шлейф от датчика нужно скрутить в косичку для уменьшения помех. Далее руководство по эксплуатации. Программа имеет 2 режима работы, это настройка и запись. Запись активируется при коротком нажатии кнопки, после чего будет ждать сигнал от пиротехнического пульта. После получения сигнала от пульта, начнется запись. При нажатии кнопки запись будет остановлена, а программа уйдет в бесконечный цикл. Настройка активируется при зажатии кнопки больше 2сек. При этом на датчик нужно положить груз с заранее известной массой(её необходимо указать в программе), по умолчанию там 141.8г. Если на карте памяти будет файл с данными, то он удалится, и будет создан новый. Далее в новый файл будут записаны данные калибровки. После будет включён режим теста, программа будет получать записи, и сравнивать их с первой записью, если изменения в пределах +-10г, то будет мигать светодиод на пине D6, а если нет, то светодиод на пине D5. При повторном нажатии кнопки, программа выйдет из режима настройки. Теперь как обработать данные. Открываем таблицу в Excel, запихиваем туда данные, после чего берём вес двигателя (в ньютонах), до его запуска, и просто делим первую запись на вес двигателя. Далее делим на получившееся число все остальные записи. При испытаниях в сильный мороз, показания будут гулять, поэтому проделывать это нужно с несколькими записями, и смотреть где отклонения меньше. Данные калибровки из режима настройки дадут показания в граммах, можно использовать для проверки работоспособности (индикатор переохлаждения датчика).
Код (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; } } } }