Траблы с кодом

Тема в разделе "Arduino & Shields", создана пользователем Kot111, 21 окт 2013.

  1. Kot111

    Kot111 Нуб

    Робот объезжающий препятствия, встречая перед собой препятствие останавливается, где косяк? Ик дальномер sharp
    Код (Text):
    int distPin = 4;
    int m1pin = 3;
    int m2pin = 10;
    int m3pin = 11;
    int m4pin = 9;

    void setup()
    {
      pinMode(m1pin, OUTPUT);
      pinMode(m2pin, OUTPUT);
      pinMode(m3pin, OUTPUT);
      pinMode(m4pin, OUTPUT);
    }
    void loop()
    {
      int val = analogRead(distPin);показания ик дальномера
      delay(100);
      if(val > 500)
      forwardd();
      else if(val < 500 && val > 400)
      turnn();
      else
      backwardd();
    )
    void forwardd() движение вперед
      {
      digitalWrite(m2pin, HIGH);
      digitalWrite(m3pin, HIGH);
      }
    void backwardd()движение назад
    {
      digitalWrite(m1pin, HIGH);
      digitalWrite(m4pin, HIGH);
    }
    void turnn()разворот
    {
      digitalWrite(m1pin, HIGH);
      digitalWrite(m2pin, HIGH);
    }
     
    Сидит мотор Шилд(l9110) 10, 11 движение вперед на 3 и 9 назад, аналоговый 4 показания дальномера
     
    Последнее редактирование: 21 окт 2013
  2. Megakoteyka

    Megakoteyka Оракул Модератор

    Неплохо было бы откомментировать код, если Вы хотите, чтобы его понимал кто-то, кроме Вас. Схема устройства тоже не помешает. Что к чему подключено?
     
  3. Kot111

    Kot111 Нуб

    Откоментировал
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    Вижу включение моторов, но не вижу выключения ни одного из них ни при каких обстоятельствах. Чтобы мотор вращался, нужно на одну ногу подать высокий уровень, а на другую - низкий. Для смены направления вращения - наоборот. У Вас получается высокий уровень на всех ногах и никто никуда не вращается.
    Тут приводится немного другой код для управления моторами. И описание логики работы шилда вроде неплохое. Не пробовали?
     
    Последнее редактирование: 22 окт 2013
  5. Kot111

    Kot111 Нуб

    Нет, но завтра попробую. И еще вопрос условие в блоке void loop правильно написанно?
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Код (Text):
    if(val > 500)
      forwardd();
    else
      if(val < 500 && val > 400)
        turnn();
      else
        backwardd();
    При val == 500 поедем назад :)

    Зачем обязательно к if писать else ?
    Можно сделать проще и понятней:
    Код (Text):
    if(val >= 500)
      forwardd();
    if(val >= 400 && val < 500)
      turnn();
    if(val < 400)
      backwardd();
    Условия составлены таким образом, что программа всегда попадет в одну из веток.
     
  7. fr0ster

    fr0ster Гик

    Код (Text):
    if(val > 500)
      forwardd();
    else
      if(val < 500 && val > 400)
        turnn();
      else
        backwardd();
    В этом коде достаточно в первом условии > на >= заменить и все будет так же, а вот проверок будет выполнено меньше, в итоге.
    Код (Text):
    if(val >= 500)
      forwardd();
    else
      if(val < 500 && val > 400)
        turnn();
      else
        backwardd();
     
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    Лишняя проверка обычно ресурсы не съедает, это же не цикл, который иногда приходится переписывать на асме.
    В итоге либо лишняя проверка, либо лишняя ступенька в лесенке, ИМХО дело вкуса :)
     
  9. fr0ster

    fr0ster Гик

    Почему не цикл? Конструкция в функции loop(), которая крутится до морковкина заговенья :), так как из цикла вызывается.
     
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    Про loop() я в курсе. Я другое имел ввиду. Обычно имеет смысл оптимизировать те участки кода, исполнение которых сильно критично ко времени. Например, когда в прерывании нужно быстро переписать массив данных.

    Вот реальный пример:
    Код (Text):
    for(i = 0; i < 32; i++)
        buffer[i] = *(unsigned short*)(8400 + sizeof(unsigned short));
    Компилятор заголовок цикла превращает в 14 инструкций,
    а тело цикла - в 4 инструкции. Т.е. одно только тело цикла, выполнившись 32 раза, сожрет 128 тактов процессора.

    В оптимизированном виде это выглядит вот так:
    Код (Text):
    asm (" pshm ar3");
    asm (" pshm ar5");
    asm (" stm #8400h,ar3");
    asm (" stm _buffer,ar5");
    asm (" nop");
    asm (" nop");
    asm (" rpt #31");
    asm (" mvdd *ar3+,*ar5+");
    asm (" popm ar5");
    asm (" popm ar3");
    Используется инструкция "rpt, count", которая повторяет следующую за ней инструкцию count+1 раз.
    Компилятор об этом почему-то не знает. Все это выполняется за 41 такт процессора.

    Флуд, однако :)
     
    Последнее редактирование: 24 окт 2013
  11. fr0ster

    fr0ster Гик

    Может и флуд, но всегда стоит помнить про цену оптимизации.
    Перевести код на ассемблер и оптимизировать его гораздо сложнее, чем просто выбрать более оптимальную конструкцию.

    ЗЫ А переносимость еще не упоминаем, оптимизация за счет переносимости - зло.
     
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Я привел пример случая, когда оптимизировать можно единственным способом - переводом на ассемблер.
    Другого способа просто не существует :)
    В остальном Вы, конечно, правы. Сперва стоит писать оптимальный код на языке высокого уровня, и только в самых критических участках делать ассемблерные вставки, если времени не хватает.
     
  13. NR55RU

    NR55RU Гик

    Чуть чуть влезу во флуд однако с вопросом относительно этого примерчика.
    Код (Text):
    buffer[i] = *(unsigned short*)(8400 + sizeof(unsigned short));
    Поправьте меня если я не прав. Если я верно понимаю данную строчку, то в правых скобках вычисляется некое значение, которое становится значением указателя на unsigned short а потом в массив записывается значение из ячейки на которую указывает вычисленный указатель, по сути в скобках вычисляется адрес ячейки в которой хранится значение ?
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    Все верно. Только там очепятка - должно быть 0x8400, но сути дела это не меняет :)