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. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Можно будет и отдельную ардуинку впихнуть, Останется только программирование победить.

    Вы моторы мелкие тестируете. Мне же надо посмотреть что могут моторы побольше. Да и у самого в голове чтоб сформировалось понимания зависимостей параметров мотора и параметров пропеллера.
    DSC00800.JPG
    Вот такие моторки дальний RC timer 5010 остальные Gartt 4114, 5010, 6016.
     
  3. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Ну, 6016 у меня нет, а 5010 и мельче вполне себе в наличии :) Просто до них руки еще не дошли.
    --- Сообщения объединены, 23 сен 2017 ---
    У меня всё есть желание сделать на ардуинке отдельное устройство датчика оборотов с высокочастотной подсветкой и корреляционным подавлением помех от внешних засветок. Но всё руки не доходят - программить там надо много :(
     
  4. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Не могу понять что за символьный массив. ошибка на нем при компеляции ...

    Куда его записать???

    Код:
    void setup()
    {
       dtostrf(ounces,4, 1, outstr);
      static char outstr[15];
      lcd.println(outstr);
    }
    
    void loop()
     
  5. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Вот получилось. только ноль стоит в левом углу а значения граммов выводятся выровненные с права.
    Код:
    void loop()
    {
      for(int i = 0;i < 10; i ++) units += scale.get_units(), 10; // усредняем показания считав 10 раз
      units /= 10; // делим на 10
    
      ounces = units * 0.035274;     // переводим унции в граммы
                
      if (ounces > 0.5)              //если вес не ничтожно мал
      {
        // подготовка буфера строки
      for (int i=7; i<11; i++) {myStr[i]=' ';}  // заполнение пробелами
      myStr[18]='\r'; // возврат каретки
      myStr[19]='\n'; // перевод строки
    
      // преобразование переменной float x в строку
      dtostrf(ounces, 4, 0, myStr);
    
      lcd.setCursor(6, 1);           // Устанавливаем курсор на вторую строку и второй символ.
      lcd.print(myStr);
    
      }
      else                           //или
      {
      lcd.setCursor(6, 1);           // Выставляем курсор...
      lcd.print(0);                  // Выводим ноль
      }
    }
    Я так понимаю во второй половине условия нужно так же резервировать 4 знака и выводить ноль. ?
    --- Сообщения объединены, 23 сен 2017 ---
    Все дописал Гляньте мож как то оптимизировать можно???
    DSC00802.JPG
    DSC00803.JPG
    DSC00804.JPG

    Код:
    void loop()
    {
      for(int i = 0;i < 10; i ++) units += scale.get_units(), 10; // усредняем показания считав 10 раз
      units /= 10; // делим на 10
    
      ounces = units * 0.035274;     // переводим унции в граммы 
                 
      if (ounces > 0.5)              //если вес не ничтожно мал
      {
             // подготовка буфера строки
      for (int i=7; i<11; i++) {myStr[i]=' ';}  // заполнение пробелами
      myStr[18]='\r'; // возврат каретки
      myStr[19]='\n'; // перевод строки
    
      // преобразование переменной float x в строку
      dtostrf(ounces, 4, 0, myStr);
     
      lcd.setCursor(6, 1);           // Устанавливаем курсор ....
      lcd.print(myStr);
      }
      else                           //или
      {
             // подготовка буфера строки
      for (int i=7; i<11; i++) {myStr[i]='0';}  // приравниваю к нолю
      myStr[18]='\r'; // возврат каретки
      myStr[19]='\n'; // перевод строки
    
             // преобразование переменной float x в строку
      dtostrf(ounces, 4, 0, myStr);
     
      lcd.setCursor(6, 1);           // Устанавливаем курсор ....
      lcd.print(myStr);
       
      }
    }
     
  6. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    , 10 в конце так и не убрали :)
    Единичный оператор не надо в фигурные скобки.
    То есть просто
    for (int i=7; i<11; i++) myStr=' ';
    Но это всё вообще не надо никак :) Позже поясню :)

    Отлично. Взяли вещественное число и вывели его в 4 байта. 5 байтом будет 0, так как в си используются null-terminated strings, то есть признаком конца строки является байт со значением нуль.
    И вывели получившуюся строку на LCD. Встаёт вопрос: а на черта тогда было резервировать под строку не менее 20 байт, заполнять её пробелами и CR/LF, если из неё используются и выводятся только 5 байт?
    Всё, что вам нужно написать - это три строки.
    dtostrf(ounces, 4, 0, myStr);
    lcd.setCursor(6, 1);
    lcd.print(myStr);
    Всё. Вообще всё.
    Проверять условие < 0.5 вообще не нужно, так как при 0 знаков после запятой dtostrf в любом случае выдаст 0 при таких значениях.
     
    Marksheider нравится это.
  7. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Ваще круто...день мучений и переписывания тыщи строчек кода превратились в три и само главное все работает как надо. Представляю сколько мне понадобится времени для реализации вольтметра с амперметром и пересчитать все в ваты. А там подъедут LED дисплеи и все по нова надо будет вникать в вывод значений на них.
    В общем спасибо, если и дальше будете помогать то буду очень благодарен.

    До меня все ни как не доходит как все таки работают эти программы.
    в каком порядке ее формировать?
    Замерить ток потом вывести его на экран, замерить напряжение потом на экран и т.д.
    или же сначала все по порядку перемерить ток, напряжение, тягу, потом все пересчитать и только после этого выводить на экран???

    как будет лучше?

    приведу полный код весов, вдруг кому нить пригодится.

    Код:
    #include "HX711.h" // библиотека тензодатчика
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h> // Библиотека дисплея
    HX711 scale(A1, A0); 
    
    byte bukva_B[8]   = {B11110,B10000,B10000,B11110,B10001,B10001,B11110,B00000,}; // Буква "Б"
    byte bukva_G[8]   = {B11111,B10001,B10000,B10000,B10000,B10000,B10000,B00000,}; // Буква "Г"
    byte bukva_D[8]   = {B01111,B00101,B00101,B01001,B10001,B11111,B10001,B00000,}; // Буква "Д"
    byte bukva_ZH[8]  = {B10101,B10101,B10101,B11111,B10101,B10101,B10101,B00000,}; // Буква "Ж"
    byte bukva_Z[8]   = {B01110,B10001,B00001,B00010,B00001,B10001,B01110,B00000,}; // Буква "З"
    byte bukva_I[8]   = {B10001,B10011,B10011,B10101,B11001,B11001,B10001,B00000,}; // Буква "И"
    byte bukva_IY[8]  = {B01110,B00000,B10001,B10011,B10101,B11001,B10001,B00000,}; // Буква "Й"
    byte bukva_L[8]   = {B00011,B00111,B00101,B00101,B01101,B01001,B11001,B00000,}; // Буква "Л"
    byte bukva_P[8]   = {B11111,B10001,B10001,B10001,B10001,B10001,B10001,B00000,}; // Буква "П"
    byte bukva_Y[8]   = {B10001,B10001,B10001,B01010,B00100,B01000,B10000,B00000,}; // Буква "У"
    byte bukva_F[8]   = {B00100,B11111,B10101,B10101,B11111,B00100,B00100,B00000,}; // Буква "Ф"
    byte bukva_TS[8]  = {B10010,B10010,B10010,B10010,B10010,B10010,B11111,B00001,}; // Буква "Ц"
    byte bukva_CH[8]  = {B10001,B10001,B10001,B01111,B00001,B00001,B00001,B00000,}; // Буква "Ч"
    byte bukva_Sh[8]  = {B10101,B10101,B10101,B10101,B10101,B10101,B11111,B00000,}; // Буква "Ш"
    byte bukva_Shch[8]= {B10101,B10101,B10101,B10101,B10101,B10101,B11111,B00001,}; // Буква "Щ"
    byte bukva_Mz[8]  = {B10000,B10000,B10000,B11110,B10001,B10001,B11110,B00000,}; // Буква "Ь"
    byte bukva_IYI[8] = {B10001,B10001,B10001,B11001,B10101,B10101,B11001,B00000,}; // Буква "Ы"
    byte bukva_Yu[8]  = {B10010,B10101,B10101,B11101,B10101,B10101,B10010,B00000,}; // Буква "Ю"
    byte bukva_Ya[8]  = {B01111,B10001,B10001,B01111,B00101,B01001,B10001,B00000,}; // Буква "Я"
    
    
    //float calibration_factor = -15.9;// калибровочная константа тензодатчика для весов 5кг
    float calibration_factor = -8.4;// калибровочная константа тензодатчика для СТЕНДА
    float units;
    float ounces;
    char myStr[5];  // текстовый массив
    
    LiquidCrystal_I2C lcd(0x3F,16,2);  // Устанавливаем дисплей
    
    void setup()
    {
      scale.set_scale();
      scale.tare();                              //Сбрасываем на 0
      scale.set_scale(calibration_factor);       //Применяем калибровку
    
      lcd.init();               // инициализация ЖК дисплея                 
      lcd.backlight();          // Включаем подсветку дисплея
    
      lcd.createChar(1, bukva_Ya);      // Создаем символ под номером 1
      lcd.createChar(2, bukva_G);       // Создаем символ под номером 2
      lcd.createChar(3, bukva_I);       // Создаем символ под номером 3
    
      lcd.setCursor(3, 0);         // перевод курсора
      lcd.print("TECTEP BM\2");    // пишем ТЕСТЕР ВМГ
      lcd.setCursor(0, 1);    // перевод курсора на строку 1, символ 5
      lcd.print("T\1\2A");    // пишем Тяга
      lcd.setCursor(11, 1);   // перевод курсора на строку 2, символ 11
      lcd.print("\2pamm");    // пишем Грамм
    
    
    }
    
    void loop()
    {
      for(int i = 0;i < 10; i ++) units += scale.get_units(); // усредняем показания считав 10 раз
      units /= 10; // делим на 10
    
      ounces = units * 0.035274;     // переводим унции в граммы
               
      dtostrf(ounces, 5, 0, myStr);
      lcd.setCursor(5, 1);
      lcd.print(myStr);
    }
    А так выглядит стенд
    DSC00807.JPG
     
    Последнее редактирование: 23 сен 2017
  8. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Можно еще упростить :)
    Отдельно переводить в граммы совершенно не обязательно. Так как можно просто изначально умножить calibration_factor на нужное значение.
    Усреднять по 10 значениям совершенно не обязательно вручную. Так как библиотека изначально содержит возможность усреднения. Достаточно написать:
    ounces =scale.get_units(10);
    И мы получим усреднённое значение за 10 измерений.
     
  9. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Помучился немного с константой она выросла до -224.5 , в результате все работает а программка весов уложилась в 4 строчки. Убрал все украшательства так вообще смех получается.
    Подскажите зачем тут <Wire.h> она за что отвечает???

    Код:
    #include "HX711.h" // библиотека тензодатчика
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h> // Библиотека дисплея
    HX711 scale(A1, A0);  
    
    float calibration_factor = -224.5;        // калибровочная константа тензодатчика-216.7для СТЕНДА -224,5 при длине луча 735 мм
    float units;
    float ounces;
    char myStr[5];  // текстовый массив
    
    LiquidCrystal_I2C lcd(0x3F,16,2);  // Устанавливаем дисплей
    
    void setup()
    {
      scale.set_scale();
      scale.tare();                              //Сбрасываем на 0
      scale.set_scale(calibration_factor);       //Применяем калибровку
    
      lcd.init();               // инициализация ЖК дисплея                  
      lcd.backlight();          // Включаем подсветку дисплея
      }
    void loop()
    {
      ounces = scale.get_units(10);     //усреднение 10 значений
      dtostrf(ounces, 5, 0, myStr);       // подготовка 5 знакомест
      lcd.setCursor(5, 1);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение грамм
    }
    
    Пошел изучать как сделать вольтметр с амперметром. Плата то уже давно готова на датчике алегро и силовым выключателем.

    Как теперь сюда начать вписывать вольтметр? просто ниже открыть кавычки {.....} и в них писать?
     
  10. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    нужна для LCD - поддерживает протокол i2c, по которому он работает.
    Ошибка:
    Если вы выводите 5 знакомест в dtostrf, то строка должна быть из 6 символов - завершающий строку ноль тоже надо куда-то запихать.
    Замечание - как глобальные лучше объявлять только те переменные, которые реально нужны как глобальные. ounces и myStr используются только в loop, причём только на текущем проходе. Поэтому их можно спокойно объявлять локально (внутри loop).
    uint16_t inU = analogRead(0);
    uint16_t inI = analogRead(1);
    float realU = float(inU) * 0.0455;
    float realI = float(inI) * 0.0776;
    Здесь пины A0 и A1, можно поменять на любые аналоговые входы по вкусу - куда подцеплен power module.
    Возможно придётся подобрать коэффициенты (китайцы с точностью сильно не заморачиваются).
     
  11. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Я вывожу 4 символа плюс знак минус, если не увеличить до 5 то знак минус смещает последний знак к граммам и он там зависает. а так вроде нормально отрабатывает. Тогда добавляя место для минуса нужно есче один знак добавить для последнего ноля?
    Вот эти две строчки и есть вольтметр с амперметром???
    А от какого опорного напряжения они меряют входное напряжение???
    При измерении тока от датчика алегро надо отнять 2.5 вольта офсетного напряжения.
     
  12. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Да. Я рекомендовал бы вообще длину строки взять с запасом, например char myStr[10]; - мало ли что :) А наезжание выводимых данных на соседнюю переменную - любимый выстрел в ногу в си :)
    Ну строки там четыре, но если надо две, то:
    float realU = float(analogRead(0)) * 0.0455;
    float realI = float(analogRead(1)) * 0.0776;
    :)
    Ну тогда
    float realI = float(analogRead(1) - 512) * 0.0776;
    Коэффициент, естессно, будет другой.
    От питательных 5В. Точность никакая, конечно. Можно переключиться на внутренне стабилизированные 1.1В, но тогда надо будет делать дополнительный делитель и на U и на I.
    https://www.arduino.cc/en/Reference/AnalogReference
    --- Сообщения объединены, 24 сен 2017 ---
    Небольшое дополнение. Для dtostrf ширина выводимого текста задаётся минимальная. То есть если там будет число 1000000, то он наплюёт на width=5 и честно выведет по данному ему адресу все 7 знаков. Если размер буфера будут недостаточным, то он будет затирать соседнюю память - он же не знает, что буфер уже закончился.
    Поэтому для полной корректности надо бы написать что-то такое:
    if ((ounces > 99999) || (ounces < -9999)) {
    lcd.print("OVER");
    } else {
    dtostrf(ounces, 5, 0, myStr); // подготовка 5 знакомест
    lcd.setCursor(5, 1); //Переводим курсор
    lcd.print(myStr); //выводим значение грамм
    }
    --- Сообщения объединены, 24 сен 2017 ---
    Небольшое дополнение. Для dtostrf ширина выводимого текста задаётся минимальная. То есть если там будет число 1000000, то он наплюёт на width=5 и честно выведет по данному ему адресу все 7 знаков. Если размер буфера будут недостаточным, то он будет затирать соседнюю память - он же не знает, что буфер уже закончился.
    Поэтому для полной корректности надо бы написать что-то такое:
    if ((ounces > 99999) || (ounces < -9999)) {
    lcd.print("OVER");
    } else {
    dtostrf(ounces, 5, 0, myStr); // подготовка 5 знакомест
    lcd.setCursor(5, 1); //Переводим курсор
    lcd.print(myStr); //выводим значение грамм
    }
    --- Сообщения объединены, 24 сен 2017 ---
    Упс, два раза почему-то паблиш прошёл. И исправить уже не могу.
     
  13. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    а выводить на экран нужно будет realU и realI.
    Где эти переменные надо объявить? глобально или внутри функции???
    --- Сообщения объединены, 24 сен 2017 ---
    Просто сижу рассматриваю примеры вольтметра , так там как то совсем все по другому.
    Для начала надо мне понять где и какие перемные объявить и вникнуть какая за что отвечает. Мозг кипит.
     
  14. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Угу.
    Они объявлены локально:
    float realU = float(analogRead(0)) * 0.0455;
    Вот это float в начале строки и объявляет локальную переменную realU типа float и сразу пишет в неё значение.
     
  15. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Выводить значения тока и напряжения нужно по отдельности? или как то одним махом все можно сделать?
    Код:
    void loop()
    {     
      char myStr1[5];                    // текстовый массив для веса
      char myStr2[5];                    // текстовый массив для напряжения
      char myStr3[5];                    // текстовый массив для амперы
    
               //Измеритель тяги
    
      float ounces;
      ounces = scale.get_units(10);               //усреднение 10 значений
      dtostrf(ounces, 5, 0, myStr1);              //Подготовка 5 знакомест
      lcd.setCursor(5, 1);                        //Переводим курсор
      lcd.print(myStr1);                          //выводим значение грамм
    
              // Вольтамерметер
     
      uint16_t inU = analogRead(2);
      uint16_t inI = analogRead(3);
      float realU = float(inU) * 0.0455;
      float realI = float(inI) * 0.0776;
    
      dtostrf(realU, 4, 0, myStr2);               //Подготовка 5 знакомест
      lcd.setCursor(0, 0);                        //Переводим курсор
      lcd.print(myStr2);                          //выводим значение вольт
    
      dtostrf(realI, 4, 0, myStr3);               //Подготовка 5 знакомест
      lcd.setCursor(10, 0);                        //Переводим курсор
      lcd.print(myStr3);                          //выводим значение Ампер
    
    
    }
    Вроде как даже работает, какие то цифры показывает, Пошел припаивать датчики тока и напряжения.
     
  16. An_private

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

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

    Замечания.
    - зачем три текстовых массива? Они всё равно используются по очереди. Для всех трёх операций достаточно одного и того же.
    - вес по прежнему выдаётся в 5 знакомест и массив в 5 байт. Должен быть минимум на 1 байт больше.
    - ток и напряжение лучше выдавать с десятыми - это примерно соответствует измерительной точности.
     
  17. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Вопрос такой, касающийся электроники. Сильно будет влиять наводками близкое расположение силовых проводов от регулятора оборотов на HX711 ?
     
  18. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Ну вот вроде все и настроил, как теперь посчитать мощность, и эффективность пропеллера?
    При подключении разных аккумуляторов от 2s до 4s точность измерения пляшет. Сотые единицы на 0,07-0,05 различаются. Я так понимаю это разрядности АЦП не хватает или как то можно повысить???
    Код:
    void loop()
    {        
      char myStr[6];                    // текстовый массив для текста
    
              //Измеритель тяги
    
      float ounces;
      ounces = scale.get_units(10);               //усреднение 10 значений
      dtostrf(ounces, 5, 0, myStr);               //Подготовка 5 знакомест
      lcd.setCursor(5, 1);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение грамм
    
              // Вольтамерметер
      
      uint16_t inU = analogRead(7);
      uint16_t inI = analogRead(6);
      float realU = float(inU) * 0.027425;
      float realI = (float(inI)-512) * 0.0776;
    
      dtostrf(realU, 5, 1, myStr);                //Подготовка 5 знакомест
      lcd.setCursor(0, 0);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение вольт
    
      dtostrf(realI, 5, 1, myStr);                //Подготовка 5 знакомест
      lcd.setCursor(9, 0);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение Ампер
    }
    
    P9240011.JPG
     
  19. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    P=U*I :)
    Effectivness = Thrust/P
    Ну так из формулы же всё понятно. Если вы целое число in умножаете на коэффициент, то 1 шаг in соответствует коэффициенту.
    Соответственно, для I у вас младший бит АЦП равен 0,0776А, для U - 0,027425В. Так что смотреть сотые вообще бессмысленно, в лучшем случае десятые.
    В реальности всё гуляет куда сильнее, как из-за лёгкого гуляния напряжения питания процессора (а он используется в качестве ref) и погрешности самого АЦП, так и из-за довольно высокого уровня ВЧ помех по питанию, создаваемых ESC.
    --- Сообщения объединены, 24 сен 2017 ---
    Побочный вопрос - у вас коэффициенты проверены? Или просто взяты мои? Так как для I коэффициент должен быть куда более "ровный"
     
  20. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Коэффициенты я подогнал. только все равно не работает ток, он скачет в 2 раза увеличивая свое значение.
    Сейчас стырил код для алегро у raefa как он работает для меня пока понять сложно но пытаюсь откалибровать и вроде как работает.
    Мож вы чем поможете???
    Код:
    const int numReadings = 10;
    float readings[numReadings];      // Массив чтения по аналоговому входу
    int index = 0;                    // Номер текущего чтения
    float total = 0;                  // Всего считано
    float average = 0;                // Среднее
    float i = 0;// - Вывод значения на индикатор
    float a = 0;
    float currentValue = 0;
    
    void loop()
    
    total= total - readings[index];       
      readings[index] = analogRead(6);        // Чтение сырого значения
    readings[index] = (readings[index]-499.71)*4.84/1024/0.0133-4.339;
    
    // Процесс обработи  данных: // 117.7-Сырое значение с датчика при 0А = 0мА // 5-5v - максимум 5В // Первое 0.04-0.04V/A(чувствительность из datasheet датчика); // +0.07 - поправочный коэффициент, чтобы выставить точный ноль;
    
      total= total + readings[index];     
        index = index + 1;                 
        if (index >= numReadings)           
          index = 0;                         
        average = total/numReadings;   //Smoothing algorithm (http://www.arduino.cc/en/Tutorial/Smoothing) 
        currentValue= average;
    
      dtostrf(currentValue, 6, 3, myStr);         //Подготовка 6 знакомест
      lcd.setCursor(8, 0);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение Ампер
    
    показывает достаточно точно буквально до сотых. с небольшим разбегом. Просто сейчас меряю на 1-2 амперах, дети спят, сделать ампер 8-10 не могу для проверки.

    --- Сообщения объединены, 24 сен 2017 ---
    У меня почему то мощность считается со знаком минус и десятичными долями. -0,7 при токе 0,33 и напряжении 14,1
    --- Сообщения объединены, 24 сен 2017 ---
    Почему в минус??
     
    Последнее редактирование: 24 сен 2017
  21. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    В смысле - скачет в два раза?
    Да там всё просто как гвоздь.
    (readings[index]-499.71)*4.84/1024/0.535+0.00
    4.84 - фактическое напряжение питания микроконтроллера (подчеркну - именно ЕГО экземпляра)
    1024 - полная шкала АЦП для 10 бит, именно такая разрядность у АЦП в AVR
    0,535 - коэффициент преобразования напряжение/ток для allegro. Значение очень странное, при прямом соединении должно быть ровно 0,04.
    499.71 - не очень удачно введённый коэффициент смещения нуля :) Теоретически должен быть таким: 2,5/4,84 * 1024 = 528,93. В данном случае видимо подобран экспериментально.
    В общем - у меня серьёзные сомнения по применению данного кода :)
    Если делать максимально прозрачно, то формула должна быть такая:
    realI = ((ADC * Uпит / 1024) - 2,5) / 0,04
    Это при прямом соединении выхода ACS со входом АЦП.
    Ну а реализация сглаживания там... (не хочу обижать модератора форума) :)
    Приведите используемый код, гляну.
     
Реклама. Купить это место.