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
    Город:
    Прокопьевск
    Имя:
    Артем
    Код:
    void loop()
    {        
      char myStr[6];                    // текстовый массив для текста
    
              //Измеритель тяги
    
      float ounces;
      ounces = scale.get_units(10);               //усреднение 10 значений
      dtostrf(ounces, 5, 0, myStr);               //Подготовка 5 знакомест
      lcd.setCursor(8, 1);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение грамм
    
              // Вольтамерметер
      
      uint16_t inU = analogRead(7);
      //uint16_t inI = analogRead(6);
    
    
      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);                           //выводим значение Ампер
    
    
      float realU = float(inU) * 0.027425;
      //float realI = float((inI)-512) * 0.69990375;
    
      dtostrf(realU, 5, 1, myStr);                //Подготовка 5 знакомест
      lcd.setCursor(0, 0);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение вольт
    
      //dtostrf(realI, 5, 2, myStr);                //Подготовка 5 знакомест
      //lcd.setCursor(9, 0);                        //Переводим курсор
      //lcd.print(myStr);                           //выводим значение Ампер
    
              // Считаем Мощность
    
      float wAt = float(realU * currentValue) ;
    
      dtostrf(wAt, 5, 1, myStr);                  //Подготовка 5 знакомест
      lcd.setCursor(0, 1);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение Ват
    
             // Эффективность грамм на ват
    
    
      float gRwAt = float(ounces / wAt) ;
    
      dtostrf(gRwAt, 5, 1, myStr);                  //Подготовка 5 знакомест
      lcd.setCursor(0, 1);                        //Переводим курсор
      lcd.print(myStr);                           //выводим значение Ват
          
    
    }
    --- Сообщения объединены, 24 сен 2017 ---
    С этим я разобрался, по даташиту мой датчик выдает 13 mV/A остальные коэффициенты тоже понял откуда. только при них при 0 амперах стенд показывает 4 ампера потому их и отнял. Контролирую токовыми клещами ток. по ним и выставляю.

    Я думаю он не обидится.:)
    --- Сообщения объединены, 24 сен 2017 ---
    А скачет в 2 раза показывает 0,7 ампер и через секунду 1,4 ампера и потом опять 0,7 ампер и так с интервалом в секунду. ( это с вашим кодом для тока)
     
    Последнее редактирование: 24 сен 2017
  3. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    бррррррр. ЧТО ЭТО??? :)
    Нуль надо подгонять с помощью именно вот этого 499,71 - это самый правильный вариант. А то подгонка нуля в двух местах - моветон :)
    ACS712 у вас какой именно? Питается он от BEC или от ардуинки?
     
  4. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Питается от бека от кготорого питается и ардуинка.
    Датчик ASC758KSB-150B на 150 ампер.
     

    Вложения:

    • ACS758LCB.pdf
      Размер файла:
      673,2 КБ
      Просмотров:
      0
  5. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Зачем он столько всяких переменных навставлял???
    Код:
    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;
     
  6. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Ага. Тогда должно быть ровно:
    (readings[index]-512)*4.84/1024/0.0133;
    Только вместо 4.84 надо вбить напряжение питания микроконтроллера (как можно более точно).
    --- Сообщения объединены, 24 сен 2017 ---
    Всё, дочку спать укладываю, завтра на всё отвечу :)
     
    Marksheider нравится это.
  7. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Заменил код. Ток вроде показывает адекватно, на сколько это возможно при малых токах на датчике алегро. А вот с мощностью творится прям жуть какая то.
    Выглядит это так, вторая строчка с лева это мощность, в начале стоит -0,7 потом -1,8 и потом вот такие большие числа вылазиют. иногда пишет -INF.
    P9250013.JPG
     
  8. An_private

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

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

    Serial monitor в ардуино умеете использовать? Там только нужную скорость обмена поставить и всё.
    Попробуйте просто на комп поотдавать значения и посмотреть - что там получается.
    Там всё просто - сначала в setup инициализируете на нужную скорость:
    Serial.begin(115200);

    потом просто выдаёте из скетча нужные значения
    Serial.print("I=");
    Serial.print(currentValue);
    Serial.print("A, U=");
    Serial.print(realU);
    Serial.print("V, P=");
    Serial.print(wAt);
    Serial.println("W");
    --- Сообщения объединены, 25 сен 2017 ---
    Теперь общие рассуждения.
    Для начала - я КРАЙНЕ не рекомендую смешивать разные алгоритмы сглаживания в одной программе. Если уж вы использовали метод усреднения 10 измерений для веса, то используйте его же и для других измерений. Причём крайне желательно делать измерения по всем параметрам как можно ближе друг к другу. А то сейчас у вас получается каша - вес вы усредняете в один момент (10 измерений в одном цикле), напряжение вы вообще не усредняете, а ток вы берёте средний за последние 10 циклов (именно так работает метод усреднения, использованный вами). Это совершенно неправильно с метрологической точки зрения.

    Далее. У вас постоянно идут конструкции вида:
    float gRwAt = float(ounces / wAt) ;
    В общем-то можно и так. Но приводить к float нужно только в том случае, если у вас исходные данные не float. То есть в данном случае достаточно было бы написать float gRwAt = ounces / wAt;
    Желательно почитать литературу о приведении типов данных в си :)
    http://citforum.ru/programming/c/h13.shtml#132
    Это не с мощностью, это с эффективностью. У вас в стопе значение мощности равно 0 (или около того). Даже единиц грамм тяги достаточно, чтобы получить эффективность в несколько миллионов грамм/вт.
    Поэтому эффективность имеет смысл считать и выводить только когда мощность больше хотя бы 2-3Вт.
     
  9. Marksheider

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

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

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

    По программе,логическая схема так сказать.
    1 производим измерения тока, напряжения, веса.
    2 производим усреднение всех показателей.
    3 (в планах) передаем на комп
    4 высчитываем мощность и эффективность.
    5 выводим на экран все что намеряли и насчитали.

    в таком алгоритме правильнее будет составление программы?

    От куда б я это мог знать когда надо приводить а когда и просто можно посчитать. Делал просто по образу и подобию.

    Читать то я читал и о переменных ( на понимание которых у меня ушло года 2 наверное так как рассказать зачем они нужны простым человеческим языком не кому)
    И о типах данных и о операциях с ними. В общем как бы поверхностно понимаю как и что но как до практики доходит ни чего не получается.

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

    В этой ячейке экрана выводится мощность. А не работает она потому что усреднение как вы сказали идет каждые 10 циклов. поэтому 9 циклов в расчете мощности творится всякая белебирда.

    Щас поробую сделать усреднение так же как и с весом .
    Для эффективности , Тут получается условие надо делать?
    --- Сообщения объединены, 25 сен 2017 ---
    И есче один такой вопрос.
    Вот когда я считаю мощность и эффективность, надо объявлять дополнительно для них переменные или нет?
     
    Последнее редактирование: 25 сен 2017
  10. An_private

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

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

    float total_w = 0.0;
    uint16_t total_i = 0;
    uint16_t total_u = 0;
    for (uint8_t i = 0; i < 10; i++) {
    total_w += scale.get_units(1);
    total_i += analogRead(6);
    total_u += analogRead(7);
    }

    float real_w = total_w / 10;
    float real_i = (float(total_i) / 10 - 512.0)*5.0/1024/0.0133;
    float real_u = float(total_u) / 10 * 0.027425;

    ну и дальше уже расчёт производных величин - мощности и эффективности
    Да. Иначе будете получать бредовые значения при малых мощностях.
    --- Сообщения объединены, 25 сен 2017 ---
    PS:
    эх, где мои 16 лет, СМ-4 с РАФОС и фортраном... :)
    --- Сообщения объединены, 25 сен 2017 ---
    Проще объявить. Иначе придётся делать каскадные вычисления, которые громоздкие и непрозрачные.
     
  11. Marksheider

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

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

    float wAt
    float wAt = (realU * currentValue) ;

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

    Учетку создал как создать проект для кода?
    --- Сообщения объединены, 25 сен 2017 ---
    Во кажись получилось https://github.com/MrMarkscheider/-/blob/master/Тестер ВМГ
     
  12. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Так не делают.
    Объявление переменной нужно компилятору для того, чтобы заранее зарезервировать под неё нужное количество памяти (ну и знать как с ней работать).
    То есть
    float wAt;
    просто говорит компилятору, что вот есть у меня такая переменная и она будет типа float, значения у неё пока нету.
    Си просто позволяет объявлять переменную и сразу же присваивать ей значение.
    Поэтому конструкции:
    float wAt;
    wAt = realU * currentValue;
    и
    float wAt = realU * currentValue;
    с точки зрения компилятора абсолютно эквивалентны.

    В других языках есть строгие правила объявления переменных, например в pascal все переменные должны быть предварительно объявлены в разделе var и объявлять переменную в теле процедуры нельзя.

    Справа сверху "+" и там выбираем New repository
     
  13. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    if(wAt > 2)
    {
    float gRwAt = float(real_gr / wAt) ; //Считаем эффективность
    }
    else
    {
    float gRwAt = 0.0 ; //выводим ноль
    }

    Ругается что не была объявлена gRwAt. Ее перед условием надо объявить или после?
     
  14. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Она не "не была объявлена", а она объявлена дважды, что прямо запрещено правилами языка.
    В данном случае надо действительно объявить переменную (до if), а затем присваивать ей то или иное значение.
    Хотя в си для подобных случаев есть специальная конструкция:
    float gRwAt = (wAt > 2) ? real_gr / wAt : 0.0;
    Но для начинающих лучше так, как у вас :)
     
  15. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Почему на гитхабе синтаксис не подсвечивается???

    В общем вы волшебник, все кажись заработало. осталось коэффициенты подогнать.
    Гляньте че получилось.
    https://github.com/MrMarkscheider/-/blob/master/Тестер ВМГ
     
  16. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Потому, что без расширения файла он не знает что подсвечивать. А у вас у файла расширения ino нету - просто текст скопирован.
    Надо коммитить прямо исходный файл.
    Щаз почитаю и покомментирую :)
     
  17. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    То есть в условии можно так написать?
    float gRwAt

    if(wAt > 2)
    {
    gRwAt = (real_gr / wAt) ; //Считаем эффективность
    }
    else
    {
    gRwAt = 0.0 ; //выводим ноль
    }
     
  18. An_private

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

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

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Все замечательно, мотор 4114 330кв с пропеллером 18" на батарейке 2s дает тягу 500 грамм на максимуме. Эффективность 12,6 гр на ватт.

    Единственное значения тока пляшут сильно, по пол ампера в верх и низ от фактического.

    Как думаете привязка к внутреннему опорному напряжению уменьшит скачки тока? или только дополнительное АЦП ставить, 16 бит.
     
  20. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Калибровали? Я у себя просто вешал груз известной массы и подгонял коэффициенты чтобы показывало правильно.
    А он так и пляшет в реале. Попробуйте на питание ESC повесить кондёр микрофарад на 4700 или больше - немного подровняется.
     
  21. Marksheider

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

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

    Ох и опасная же эта штука, винта совсем не видно при работе, прям страшно подумать что может случиться если залезть под работающий винт.:eek:
     
Реклама. Купить это место.