очень медленно работает arduino

Тема в разделе "Arduino & Shields", создана пользователем Alex36, 12 апр 2019.

  1. Alex36

    Alex36 Нуб

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

    В проекте я использую Arduino nano, OLED 1,3 i2c
    , nrf24l01. в кочестве датчиков угла поворота два потенциометра. Проблема именно с пультом, после того как подключил библиотеку U8GLIB и нарисовал графику программа цикл проходит примерно за 100мс сужу по морганию диода при отправке в порт, а если начинаю массив перадавать по радио то вообще еще раз в 10 медленее и все лагает, ужас какой то, помогите разобраца я недавно ардуиной занялся.

    данные с ацп у меня в коде не 0-1023 так как при усреднении часть значений терялась до примерно 1018, подбирал экспериментально.

    На приемной стороне сервы 0-270 25кг к приемной стороне притензий нет.





    Код (C++):
    #include "U8glib.h"
    U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); //SDA_A4; SCL_A5;  I2C / TWI 1.3"
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    int data[2];        //массив для хранения и передачи данных
    const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба"
    RF24 radio(9, 10); // CE, CSN


    const byte averageFactor = 5;  // коэффициент сглаживания показаний
                                    // чем выше, тем больше "инерционность"
    int bat = 0; // переменная батареи фильтрованных значений АЦП
    float volt;   // переменная для напряжения батареи
    int asimut;
    int elevation;





    void setup() {

    radio.begin();
      delay(2);
      radio.setChannel(9); // канал (0-127)
      radio.setDataRate(RF24_1MBPS);      // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS
                                          // RF24_250KBPS на nRF24L01 (без +) неработает.
                                          // меньше скорость, выше чувствительность приемника.
      radio.setPALevel(RF24_PA_MIN);      // мощьность передатчика, RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM,
      radio.openWritingPipe(pipe);        // открываем трубу на передач
    u8g.setFont(u8g_font_8x13);  //шрифт
    }



    void loop() {

    int elevation_lcd;
    int asimut_lcd;
    int asimut_grad;
    int elevation_grad;

    //ЭЛЕВАЦИЯ ВЫЧИСЛЕНИЯ_______________________________

    elevation = (elevation * (averageFactor - 1) + analogRead(1)) / averageFactor;  // ФИЛЬТРАЦИЯ ЗНАЧЕНИЙ АЦП
    elevation_lcd = map(elevation, 0, 1018, 0, 124); // вычисление координат указателя
    elevation_grad = map(elevation, 0, 1018, 0, 90); // вычисление градусов

    //АЗИМУТ ВЫЧИСЛЕНИЯ_______________________________

    asimut = (asimut * (averageFactor - 1) + analogRead(2)) / averageFactor; // ФИЛЬТРАЦИЯ ЗНАЧЕНИЙ АЦП
    asimut_lcd = map(asimut, 0, 1018, 0, 124); // вычисление координат указателя
    asimut_grad = map(asimut, 0, 1018, -135, 135); // вычисление градусов

    //БАТАРЕЯ ВЫЧИСЛЕНИЯ_______________________________

    bat = (bat * (averageFactor - 1) + analogRead(3)) / averageFactor;  // ФИЛЬТРАЦИЯ ЗНАЧЕНИЙ АЦП
    volt = bat / 196; // вычисление напряжения

    //ПЕРЕДАЧА ДАННЫХ_______________________________________

    //data[0] = analogRead(1);   // фильтрованые значение в массив
    //data[1] = analogRead(2);   // фильтрованые значение в массив
    //radio.write(&data, sizeof(data)); // отправляем данные и указываем сколько байт пакет

    //__________________________________________________________

    u8g.firstPage(); // начало вывода на дисплей
    do {    



    //ЭЛЕВАЦИЯ ВЫВОД НА ДИСПЛЕЙ____________________________________________

    u8g.drawBox(elevation_lcd, 20, 4, 4); // укозатель
    u8g.drawRFrame(0, 18, 128, 8, 1); // шкала
    u8g.drawLine(64, 19, 64, 24);  // шкала
    u8g.drawLine(32, 23, 32, 24);  // шкала
    u8g.drawLine(96, 23, 96, 24);  // шкала
    u8g.setPrintPos(0, 13);
    u8g.print("ELEVATION");
    u8g.setPrintPos(85, 13);
    u8g.print(elevation_grad); //вывод градусов

    //АСИМУТ  ВЫВОД НА ДИСПЛЕЙ____________________________________________



    u8g.setPrintPos(0, 39);
    u8g.print("ASIMUT");
    u8g.drawRFrame(0, 43, 128, 8, 1);  // шкала
    u8g.drawLine(64, 43, 64, 49);      // шкала
    u8g.drawLine(22, 43, 22, 49);      // шкала
    u8g.drawLine(106, 43, 106, 49);    // шкала
    u8g.drawLine(43, 48, 43, 49);      // шкала
    u8g.drawLine(85, 48, 85, 49);      // шкала
    u8g.setPrintPos(64, 39);
    u8g.print(asimut_grad); // вывод градусов
    u8g.drawBox(asimut_lcd, 45, 4, 4); // указатель

    //БАТАРЕЯ  ВЫВОД НА ДИСПЛЕЙ____________________________________________


    u8g.drawRFrame(0, 55, 15, 8, 1); //значек батареи
    u8g.drawFrame(14,57,3,4);        //значек батареи
    u8g.drawBox(2, 57, 3, 4);        //значек батареи
    u8g.drawBox(6, 57, 3, 4);        //значек батареи
    u8g.drawBox(10, 57, 3, 4);       //значек батареи
    u8g.setPrintPos(22, 64);
    u8g.print("RX");
    u8g.setPrintPos(70, 64);
    u8g.print("TX");
    u8g.setPrintPos(42, 64);
    u8g.print(volt, 1);


    //ЗНАК АНТЕННЫ____________________________________________
    u8g.drawLine(127, 4, 127, 12);
    u8g.drawLine(125, 6, 125, 12);
    u8g.drawLine(123, 8, 123, 12);
    u8g.drawLine(121, 10, 121, 12);
    u8g.drawLine(119, 12, 119, 12);
    //_____________________________________________________

    } while( u8g.nextPage() ); //конец вывода на дисплей





    }
     

    Вложения:

  2. parovoZZ

    parovoZZ Гуру

    Экран I2C? Меняй на SPI. А вообще ответ очевиден - никогда из конструктора майбах не получится. Только коляска Серпуховича. Поэтому полный отказ от абдурино библиотек и кода и переход на нативное программирование. Возможно, что придётся сменить кварц на максимальную частоту для МК.
     
  3. ostrov

    ostrov Гуру

    Тормоза явно с выводом на экран. Хрен знает как библиотека работает, может быть она сама не оптимальная. А вообще, зачем обновлять изображение слишком часто? Может делать картинку раз в секунду, а остальное постоянно? Как вариант, вывести задачу отрисовки на отдельный МК, тогда главный будет работать быстро, а тупить "видеокарта".
     
    Andrey12 нравится это.
  4. Разрешение экрана 128*64 = 8192
    Интерфейс i2c, частота 100кГц.
    В i2c каждый 8й байт накладной, значит эффективная частота 100000/8*7 = 87500.
    Итого только на передачу одного кадра уходит 8192/87500 = 0,09с., а этот кадр еще нужно нарисовать.
     
  5. DetSimen

    DetSimen Guest

    каоче, библиотеку и идеологию вывода на экран меняй
     
    Andrey12 нравится это.
  6. vvr

    vvr Инженерище

    обновляйте дисплей только при изменении какого то параметра, выводимого на него.
     
    Vovka и ostrov нравится это.
  7. Vovka

    Vovka Гик

    Общение с внешней переферией загнать в прервания и будет "шо самолет" ;)
     
  8. ostrov

    ostrov Гуру

    Ага, особенно библиотечные функции с незнакомым содержимым и с ожиданием ответа от периферии. Как самолет будет вообще все. Сбитый.
     
  9. Vovka

    Vovka Гик

    Библиотечные функции загонять в прерывания - лично у меня даже в мыслях такого не было!
     
  10. ostrov

    ostrov Гуру

    В примере ТС именно так все и происходит. Да и не для того прерывания, чтобы ускорять или камень разгружать.
     
  11. Vovka

    Vovka Гик

    Что-то я в исходнике ТС-а не увидел явного использования прерываний :(
    А для чего?
     
  12. parovoZZ

    parovoZZ Гуру

    Чтобы эффективно писать программы для дохлых МК, необходимо хорошо знать архитектуру МК и происходящие внутри процессы. Если нет - то берём малинку - малинка все стерпит.
     
  13. Vovka

    Vovka Гик

    Может для начала нужно быть Программистом?
     
  14. vvr

    vvr Инженерище

    вот энто правильно, ведь здеся каждый второй на малине элементарно напишет ну всё что хош)))))
     
  15. parovoZZ

    parovoZZ Гуру

    Да. Но второе не отменяет первое.
     
  16. ostrov

    ostrov Гуру

    От перестановки слагаемых сумма не меняется. Если МК может делать Н-тактов в секунду, больше он не сделает хоть с прерываниями, хоть нет. Главное уметь выкинуть лишнее, а лучше изначально не добавлять. В примере ТС ускорять перерисовкой не постоянно, а раз в какое-то время и не весь экран целиком, а там где он меняется, как советовали выше. Ну, или выделять отдельный МК для экранчика.
     
  17. Vovka

    Vovka Гик

    Совсем не меняется: например, опрашивать в прерывании кнопки или опрос тех же кнопок с использованием всеми любимой функции delay() :cool:
     
  18. ostrov

    ostrov Гуру

    Открою страшную тайну: можно опрашивать и без прерываний, и без delay()!