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
    Город:
    Прокопьевск
    Имя:
    Артем
    Я так понимаю вот эта часть выводит этот stop? как оставить работу кнопки как есть но во время теста на месте stop выводилася тяга?

    откоментить не могу так как не совсем понимаю что тут происходит в этом коде.

    Код:
    for (uint8_t i = 4; i < 16; i++) line2[i] = ' ';
      itoa(pwm_value, line2 + 4, 10);
      for (uint8_t i = 0; i < 16; i++) if (line2[i] == 0) line2[i] = ' ';
    
      if (now_key3 == HIGH)
      {
        uint8_t i = 0;
        while (stop_line[i] != 0)
        {
          line2[i + 12] = stop_line[i];
          i++;
        }
        Serial.println("STOP");
      } else {
        for (uint8_t i = 12; i < 16; i++) line2[i] = ' ';
        Serial.println("RUN");
      }
     
  3. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Я просил откоммитить :) То есть выложить текущую версию на github, чтобы я мог её посмотреть :)
    Да. Там сделано просто:
    - сперва в массиве line2 байты с 4 по 15 забиваются пробелами
    - потом в него начиная с 4ой позиции выводится значение PWM
    - ищется - где-же оно закончилось (байт со значением 0) и забивается вместо нуля тот же пробел
    - проверяем кнопку
    - если кнопка не нажата (high), то копируем содержимое stop_line в line2 начиная с позиции 12 (можно то же самое сделать с помощью библиотечной strcpy, но она скопирует и 0, что мне не нужно)
    - если кнопка нажата, то просто забиваем пробелами позиции с 12 по 15
    всё
     
  4. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    :whistling: Теперь контролер глючит, перезагружает экран каждые пол секунды
    Код:
    char myStr[6];
    
        lcd.setCursor(12,1);
        if (now_key3 == HIGH)
        {
        lcd.print(stop_line);
        Serial.println("STOP");
        } else {
        dtostrf(real_weight, 4, 0, myStr);
        lcd.print(myStr);
        Serial.println("RUN");
        }
     
  5. An_private

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

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

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

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

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    почитал, ужаснулся :)
    основная проблема - у вас месиво двух методов - вывода в индикатор напрямую и вывода в промежуточный буфер (line1/line2) и потом в индикатор.
    В результате у вас затирается то, что выдано напрямую, так как выдача line1/2 идёт в самом конце.
    Далее. Несмотря на многочисленные напоминания про то, что элементы массива индексируются с нуля и под этот нуль нужен отдельный байт - я опять вижу:
    char line1[20] = "U=12.0V I=1.5A ";
    char line2[20] = "PWM=1000 STOP ";
    и в конце
    line1[40] = 0;
    line2[40] = 0;
    ????
    Это как? В массивах 20 элементов с индексами от 0 до 19, а нуль пишется в 40 (!!!) элемент.
    Следует помнить, что в си нет проверки допустимости индекса массива, поэтому вы просто записываете этот 0 в совершенно случайное место памяти.
    Причём следует помнить, что если в массиве есть нулевой элемент не в конце, то любой процедурой выдачи всё, что после него - игнорируется. Поэтому у меня этот 0 везде затирался.
     
  8. Marksheider

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

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

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

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

    Код:
    char weight_line[] = "Weig";
    
    
    for (uint8_t i = 4; i < 19; i++) line2[i] = ' ';
      itoa(pwm_value, line2 + 4, 10);
      for (uint8_t i = 0; i < 19; i++) if (line2[i] == 0) line2[i] = ' ';
    
      if (now_key3 == HIGH)
      {
        uint8_t i = 0;
        while (stop_line[i] != 0)
        {
          line2[i + 12] = stop_line[i];
          i++;
        }
        Serial.println("STOP");
      } else {
        uint8_t i = 0;
        line2[i + 9] = weight_line[i];
        i++;
        dtostrf(real_weight, 4, 0, line2 + 14) ;
        line2[18] = 'g';
       
       
        Serial.println("RUN");
      }
     
  10. An_private

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

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

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

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

    Вопрос, почему нельзя переместить букву 'g' на край экрана? в 19 знакоместо? в нем ничего не отображается ели туда что либо записать.

    Код:
     if (now_key3 == HIGH)
      {
        uint8_t i = 0;
        while (stop_line[i] != 0)
        {
          line2[i + 12] = stop_line[i];
          i++;
        }
        Serial.println("STOP");
      } else{
        uint8_t i = 0;
        while (weight_line[i] != 0) {
        line2[i + 9] = weight_line[i];
        i++;
        dtostrf(real_weight, 4, 0, line2 + 14) ;
        line2[18] = 'g';
        }
      
        Serial.println("RUN");
      }
    --- Сообщения объединены, 12 ноя 2017 ---
    Дошло... только зачем тогда в 19 знак мы ноль загоняем???
    Код:
    line1[19] = 0;
      line2[19] = 0;
     
    Последнее редактирование: 12 ноя 2017
  12. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Гляньте код пожалуйста. https://github.com/MrMarkscheider/Tester-VMG/blob/master/tester.ino#L174
    Разобрался с экранчиком, вывел во все 4 строчки то что хотел. Но как только добавляю 3 и 4 строки первая отказывается показывать ток и напряжение. В чем загвоздка не могу сообразить. помогите.
    PB120018.JPG
    PB120019.JPG
    PB120020.JPG
     
  13. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Откуда ж я знаю? :) Разве у меня в 19ый знак ноль запихивался? ;)
    А dtostrf зачем в цикл засунули? Причём аж в двух местах.
    И не забывайте делать нормальное форматирование текста - всё, что внутри if и циклов - должно быть смещено вправо.
    Ну так сколько можно повторять, что если массив объявлен как
    char line1[19];
    то в массиве находятся 19 элементов с индексами от 0 до 18 (!!!).
    И делая
    line1[19] = 0;
    вы пишете уже за пределы массива.

    И почему 0 добавляется в конец только первой и второй строки?
    3+11 = 14 , а не 15.
    А тут где забивание нуля?
     
  14. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Массив надо объявлять столько сколько знаков в строчке, тоесть 20 а уже значения распределеять с учетом ноля,так чтоль?.
    Вот этот ноль прям обязательно нужно добавлять в конец каждой строки???
    потому что без цикла не отображалось ничего, а с ним работает.:whistling:

    Линия должна собираться прям четко по знакоместам, если хоть один знак встает не на свое место то линия не отображается. так чтоль?

    ну у вас экран на 16 символов был поэтому и не в 19ый вы его запихивали ноль этот.

    Гляньте вот так корректно будет написан код. Вроде как все показывает и работает и переключается. массив line сделал на 20 знаков.

    Код:
     dtostrf(realU, 4, 1, line1 + 2);        //собираем значение напряжения
      line1[6] = 'V';
       
      dtostrf(realI, 4, 1, line1 + 10);       //собираем значение тока
      line1[14] = 'A';
       
      for (uint8_t i = 4; i < 19; i++) line2[i] = ' ';
      itoa(pwm_value, line2 + 4, 10);
      for (uint8_t i = 0; i < 19; i++) if (line2[i] == 0) line2[i] = ' ';
    
      if (now_key3 == HIGH)
      {
        uint8_t i = 0;
        while (stop_line[i] != 0)
        {
          line2[i + 12] = stop_line[i];
          i++;
        }
        Serial.println("STOP");
      } else{
            uint8_t i = 0;
            while (weight_line[i] != 0) {
                line2[i + 9] = weight_line[i];
                i++;
            }
        dtostrf(real_weight, 4, 0, line2 + 14) ;
        line2[18] = 'g';
        Serial.println("RUN");
      }
       
          dtostrf(real_w, 4, 0, line3 + 2);    //собираю  строчку3 добавляю мощность
          line3[6] = 'w';                     
          dtostrf(real_wg, 4, 1, line3 + 11);  //добавляю эффективность в строчку 3
          line3[15] = 'g';
          line3[16] = '/';
          line3[17] = 'w';
          dtostrf(real_wg, 3, 0, line4 + 5);   //собираю строчку 4 здесь будет скорост вращ верхнего мотора
          line4[8] = ' ';
          dtostrf(real_wg, 3, 0, line4 + 14);  //а тут нижнего мотора.
         
      line1[19] = 0;
      line2[19] = 0;
      line3[19] = 0;
      line4[19] = 0;
     
  15. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Помните вы мне рассказывали про усреднения.
    помогите добавить усреднение тока. Я к сожалению так и не понял этой формулы до конца.
    что такое scale.get_units ?
    У меня из за того что скачет ток , на экранчике скачат все остальные показатели, и не понятно чего они там показывают. Конденсаторы я припаял и на входе датчика тока и на выходе , но это мало помогло.
    --- Сообщения объединены, 13 ноя 2017 ---
    Посмотрел сейчас ваш исходник, вы получается для 16 значной строчки создаете 17 символьный массив, и потом ноль забиваете в последний знак который находится за пределами экранчика... ООО а разве так можно???:cautious:
     
  16. An_private

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

    Регистрация:
    6 июн 2016
    Сообщения:
    595
    Город:
    Санкт-Петербург
    Имя:
    Андрей Коробейников
    Нет, массив надо объявлять на один символ больше - последний байт под финальный ноль.
    Да. А как иначе print узнает - когда закончилась строка? Есть два подхода - старый паскалевский (длина строки хранится в нулевом байте массива, а сами символы идут с первого элемента) и сишный - длина строки в явном виде не видна, конец строки задаётся нулевым байтом. Это называется null terminated string.
    https://ru.wikipedia.org/wiki/Нуль-терминированная_строка
    Не так. Дело в том, что всякие служебные процедуры типа dtostrf записывают в выходной буфер тоже null terminated string. И если мы просим от dtostrf сделать 4 символа, то реально в выходную строку пишется пять байт - 4 символа результата преобразования и нулевой байт. Если его оставить на месте, то print дойдёт до нулевого байта в середине строки и просто прекратит вывод. Поэтому у меня этот нолик везде забивается пробелом или ещё чем-нибудь.
    Есть альтернативный вариант, но он ест чуть больше ресурсов - преобразовывать в промежуточную строку и потом копировать результат в основную. То есть примерно так (цифры с потолка):
    char tmp_str[10];
    dtostrf(data, 5, 1, tmp_str);
    memcpy(line1 + 5, tmp_str, strlen(tmp_str));
    Нужно :) Ноль не выводится - это просто признак конца строки для любого print.
    Результат единичного измерения веса.
    Так а чего там не понимать. Мы делаем аккумулятор. В каждом цикле мы отрезаем от него 10% и добавляем к нему 10% от измеренного значения. Получаем классическое интегральное сглаживание.
    --- Сообщения объединены, 13 ноя 2017 ---
    Да, кстати, вместо:
    uint8_t i = 0;
    while (weight_line != 0) {
    line2[i + 9] = weight_line;
    i++;
    }
    можно написать просто
    memcpy(line2 + 9, weight_line, strlen(weight_line))
    результат будет тот же. Просто моя конструкция чуть эффективнее за счёт совмещения копирования и определения конца строки.
     
  17. Marksheider

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

    Регистрация:
    1 дек 2016
    Сообщения:
    332
    Город:
    Прокопьевск
    Имя:
    Артем
    Вот так правильно будет усреднять? Я хочу оставить так чтоб realI передавался в компьютер как есть чтоб там и усреднялся вашей программой, а indI уже выводить в экранчик и проводить с ним расчеты мощности и т.д.
    Код:
    uint16_t inI = analogRead(6);
    float realI = (float(inI)- 512.0)*5.0/1024/0.0133;   //Корректировка тока
    float indI = (indI * 0.9) + (realI / 10);  // усреднение.
    
     
  18. An_private

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

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

    static float indI;
    float realI = (float(analogRead(6))- 512.0)*5.0/1024/0.0133; //Корректировка тока
    indI = (indI * 0.9) + (realI / 10); // усреднение.
     
  19. Marksheider

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

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

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

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

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

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