roboforum.ru

Технический форум по робототехнике.

Подключение ИК локатора

Подключение ИК локатора

Montoya » 27 мар 2008, 21:13

Приветствие! Собрал я вот эту схемку ик локатора, все работает, но теперь у меня появился вопрос, как установить этот локатор на робота? Я так понимаю надо убрать LED2 и на его место подрубить порт МК робота, а в прошивку робота добавить счетчик сигналов, чтобы при определенном количестве их робот останавливался или просто объезжал препятствие.
Вложения
ir_locator.gif
ir_locator.gif (5.48 КиБ) Просмотров: 2763

Re: Подключение ИК локатора

Кирилл » 27 мар 2008, 21:28

Именно так. Если есть большое желание можно по SPI связаться с контроллером.

Re: Подключение ИК локатора

Montoya » 27 мар 2008, 21:54

Ясно, будем химичить с прошивкой :) , наверно возьму кусок прошивы для локатора,отвечающий за прием сигналов от ТСОПа, правда придется переписывать код с асмы на си.....

Re: Подключение ИК локатора

Myp » 27 мар 2008, 22:37

да прольётся на тебя манна небесная
да возьмёшься ты за поиск по форуму
и да отыщется вся инфа по тсопам и нормлаьному коду для них на си
и да напишешь ты код великий для основного процессора в роботе
и да не будешь городить ахинею из кучи разных мк когда всё можно сделать на одном :)

Re: Подключение ИК локатора

Montoya » 27 мар 2008, 23:00

аффтар жжот, епть))
А насчет кучи МК, просто у мну уже готовый "робот", и мне не хотелось лезть к нему в кишки (уж слишком там много проводов :) ) ради экспериментов с локатором, который мне пришлось пересобирать 2 раза, поэтому и собрал локатор отдельно на макетке и на другом МК. Кстати, в приведенной мной схеме транзистор нафиг не нужен,вместо него надо ставить переменный резистор между диодом и МК дето на 1кОм и меньше и им регулировать чувствительность.

Re: Подключение ИК локатора

Сергей » 28 мар 2008, 00:31

аминь

Re: Подключение ИК локатора

Montoya » 03 апр 2008, 20:56

Эх...долго я парился над всем этим... в итоге получилась куча вопросов :( :
Какая должна быть чувствительность у локатора (на каком расстоянии срабатывать) ?
Если использовать отдельный локатор на отдельном мк (как у меня), то каким должно быть количество полученныйх сигналов на главном мк,чтобы включать объезд? Надо же знать скоко и когда локатор послал импульсов и скок из них получил?
А если не заморачиваться на 2х мк, то есть ли у кого-либо нормальный рабочий код на Си для локатора? Я ниче нормального не нашел....может просто я не умею искать? :)

Re: Подключение ИК локатора

yak-40 » 03 апр 2008, 21:31

Я, вот в этой конструкции http://www.roboforum.ru/viewtopic.php?f=10&t=3792
пошел таким же путем. Тоже не стал заморачиваться. :)
На управление всей системой стоит Мега32, а двухканальный ИК излучатель собран на Тинке13.
Работает нормально.
Montoya писал(а):каким должно быть количество полученныйх сигналов

Количество принятых сигналов должно совпадать с количеством переданных :)
Montoya писал(а):Какая должна быть чувствительность у локатора

Зависит от габаритов робота. Регулируется экспериментально.
Могу прислать код и схему излучателя для Тини13, если надо, скажи куда.
На прием стоит обычные ТСОПы :)

Удачи!

Re: Подключение ИК локатора

Montoya » 03 апр 2008, 22:59

Ооо,шли на gerasimoff<ПЁСЕГ>hotmail.com , заранее СПАСИБО! :)

Re: Подключение ИК локатора

Montoya » 06 апр 2008, 20:32

Народ, выручайте! Мне для выставки ко вторнику надо на робота прилепить ик бампер,а у меня нифига не получается с прошивкой :( . Бампер сделан на основе главного МК.
Мне нужно вот сюда
Код: Выделить всёРазвернуть
#include <inttypes.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>

// назначение определений для удобства работы с периферией
#define OUT PORTB
#define MOTOR_F      PB5
#define MOTOR_B      PB3
#define TURN_L      PB4
#define TURN_R      PB2

#define IN PIND
#define LIGHT_R  PD0
#define LIGHT_L  PD1
#define BUMPER_F PD3


#define sbi(port,bit)  port |=  (1<<(bit))
#define cbi(port,bit)  port &= ~(1<<(bit))
#define outb(port,bit)  port = bit

// Возможные режимы движения
enum {STOP, F, FR, FL, B, BR, BL};

//------------------------------------------------------------------------------
// Задержка t х 10ms
//------------------------------------------------------------------------------
#define F_CPU 4000000
#define K_DELAY_10ms   F_CPU/600
void Delay_10ms(unsigned char t) {
  unsigned int i;
  if (t==0) return;
  while (t--) for(i=0;i<K_DELAY_10ms; i++);
}

// таблица вероятностей для выбора направления движения
// исходя из текущего направления движения
unsigned char p[7][7] = {
{14,43,   57,   71, 7, 100, 100},
{7,   43,   71,   100,100,100,100},
{7,   50,   93,   100,100,100,100},
{7,   50,   57,   100,100,100,100},
{29,29,   29,   29,   57,   79,  100},
{36,36,   36,   36,   71,   93,    100},
{36,36,   36,   36,   71,   79,    100},
};


// текущее направление движения
unsigned char this_move;

//------------------------------------------------------------------------------
// Включение комбинации моторов для движения в заданном направлении
//------------------------------------------------------------------------------
void go(unsigned char direction){

  switch (direction) {
   case STOP:
    cbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case F:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FR:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FL:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;

  case B:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BR:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BL:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;
  }
}

//------------------------------------------------------------------------------
// Выбор направления движения в следующем шаге по таблице вероятностей
//------------------------------------------------------------------------------
unsigned char next_move(void){
   unsigned char pp, i;

   pp = rand()/327;     // получаем случайное число 0..99
   for (i=0;i<7;i++){   // ищем соответствие в таблице вероятностей
      if (p[this_move][i] > pp) break;
   }
   this_move = i;       // записываем новое полученное направление как текущее
   return(i);
}

SIGNAL(SIG_INTERRUPT1)
{
   if(this_move==FR) go(BL);
   if(this_move==FL) go(BR);
   else go(B);
   Delay_10ms(2000);   
   Delay_10ms(2000);
   this_move=B;
}


//------------------------------------------------------------------------------
// "Случайное блуждание"
//------------------------------------------------------------------------------
unsigned char walk(void){
   // этот цикл организует "свободное блуждание" пока
   // нет сигнала ни от одного из датчиков освещенности
   while((bit_is_set(IN, LIGHT_R)) && (bit_is_set(IN, LIGHT_L))){
       go(next_move());   // получаем следующее направление движения и
       Delay_10ms(250);   
   }
   // этот цикл организует движение на свет, пока
   // есть сигнал хотя бы от одного из датчиков освещенности
   while((bit_is_clear(IN, LIGHT_R)) || (bit_is_clear(IN, LIGHT_L))){
       if((bit_is_clear(IN, LIGHT_R)) && (bit_is_clear(IN, LIGHT_L))) go(F);
       else if(bit_is_clear(IN, LIGHT_R)) go(FR);
       else if(bit_is_clear(IN, LIGHT_L)) go(FL);
   }

   return(0);
}

//------------------------------------------------------------------------------
// Главная программа
//------------------------------------------------------------------------------
int main(void)
{
  DDRB  = 0xff;  // назначаем все линии порта B на выход
  PORTB = 0x00;  // и устанавливаем на них низкий уровень

  DDRD  = 0x00;  // назначаем все линии порта D на вход
  PORTD = 0xff;  // подключаем внутренние нагрузочные резисторы

  // разрешаем прерывания int0 и int1
  outb(GIMSK, (1<<INT0)|(1<<INT1));

  // запрос на прерывание - по спадающим фронтам на int0 и int1
  outb(MCUCR, (1<<ISC01)|(1<<ISC11));

  // разрешаем прерывания
  sei();         

  // запускаем главный цикл
  while(1) walk();

}

надо добавить это
Код: Выделить всёРазвернуть
#include<avr/io.h> 
#include<avr/delay.h>
#define time 1.157407407//время задержки
#define F_CPU 4000000UL

int main(void)
{
PORTB = PORTD = 0xFF;
//на РВ3 стоит ИК приемник
DDRB |=_BV(PB4);//ИК светодиод

DDRD |=_BV(PD6);//cветодиод

while(1)
{
int i;
for(i=0;i<10;i++){
_delay_loop_1(time);
PORTB&=~_BV(PB4);//включаем ИК светодиод
_delay_loop_1(time);
PORTB|=_BV(PB4);//выкл Ик светодиод
}

int u;
for(u=0;u<14;u++){

if(bit_is_clear(PINB,PB3)){//если есть сигнал на Ик приемнике
PORTD &=~_BV(PD6);//Включаем светодиод
}else{
PORTD|=_BV(PD6);//если нет сигнала - выключаем

}

}

}
}

но чтобы не светик зажигать,а объезжать препятствие... У меня на PD2 стоит тсоп, на PD3 ик излучатель... В первом коде на PD3 висит контактный бампер,но его не будет.

Re: Подключение ИК локатора

Montoya » 13 апр 2008, 23:04

С выставкой я пролетел....
Не знаю, возможно ли в таком варианте соединить эти два кода...
Вот мой НЕ работающий вариант:

Код: Выделить всёРазвернуть
#include <inttypes.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include<avr/io.h>
#include<avr/delay.h>
#define time 1.157407407//время задержки

// назначение определений для удобства работы с периферией
#define OUT PORTB
#define MOTOR_F      PB5
#define MOTOR_B      PB3
#define TURN_L      PB4
#define TURN_R      PB2

#define IN PIND
#define LIGHT_R  PD0
#define LIGHT_L  PD1
#define BUMPER_F PD3


#define sbi(port,bit)  port |=  (1<<(bit))
#define cbi(port,bit)  port &= ~(1<<(bit))
#define outb(port,bit)  port = bit

// Возможные режимы движения
enum {STOP, F, FR, FL, B, BR, BL};

//------------------------------------------------------------------------------
// Задержка t х 10ms
//------------------------------------------------------------------------------
#define F_CPU 4000000
#define K_DELAY_10ms   F_CPU/600
void Delay_10ms(unsigned char t) {
  unsigned int i;
  if (t==0) return;
  while (t--) for(i=0;i<K_DELAY_10ms; i++);
}

// таблица вероятностей для выбора направления движения
// исходя из текущего направления движения
unsigned char p[7][7] = {
{14,43,   57,   71, 7, 100, 100},
{7,   43,   71,   100,100,100,100},
{7,   50,   93,   100,100,100,100},
{7,   50,   57,   100,100,100,100},
{29,29,   29,   29,   57,   79,  100},
{36,36,   36,   36,   71,   93,    100},
{36,36,   36,   36,   71,   79,    100},
};


// текущее направление движения
unsigned char this_move;

//------------------------------------------------------------------------------
// Включение комбинации моторов для движения в заданном направлении
//------------------------------------------------------------------------------
void go(unsigned char direction){

  switch (direction) {
   case STOP:
    cbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case F:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FR:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FL:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;

  case B:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BR:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BL:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;
  }
}

//------------------------------------------------------------------------------
// Выбор направления движения в следующем шаге по таблице вероятностей
//------------------------------------------------------------------------------
unsigned char next_move(void){
   unsigned char pp, i;

   pp = rand()/327;     // получаем случайное число 0..99
   for (i=0;i<7;i++){   // ищем соответствие в таблице вероятностей
      if (p[this_move][i] > pp) break;
   }
   this_move = i;       // записываем новое полученное направление как текущее
   return(i);
}






//------------------------------------------------------------------------------
// "Случайное блуждание"
//------------------------------------------------------------------------------
unsigned char walk(void){
   // этот цикл организует "свободное блуждание" пока
   // нет сигнала ни от одного из датчиков освещенности
   while((bit_is_set(IN, LIGHT_R)) && (bit_is_set(IN, LIGHT_L))){
       go(next_move());   // получаем следующее направление движения и
       Delay_10ms(250); 
}
   int i;
for(i=0;i<10;i++){
_delay_loop_1(time);
PORTB&=~_BV(PB1);//включаем ИК светодиод
_delay_loop_1(time);
PORTB|=_BV(PB1);//выкл Ик светодиод
}
   int u;
for(u=0;u<14;u++){
int count;
count=0;
if(bit_is_clear(PIND,PD1)){//если есть сигнал на Ик приемнике
count++;
if(count==14) {
   if(this_move==FR) go(BL);
   if(this_move==FL) go(BR);
   else go(B);
   Delay_10ms(2000);   
   Delay_10ms(2000);
   this_move=B;
}
}
}
   // этот цикл организует движение на свет, пока
   // есть сигнал хотя бы от одного из датчиков освещенности
   while((bit_is_clear(IN, LIGHT_R)) || (bit_is_clear(IN, LIGHT_L))){
       if((bit_is_clear(IN, LIGHT_R)) && (bit_is_clear(IN, LIGHT_L))) go(F);
       else if(bit_is_clear(IN, LIGHT_R)) go(FR);
       else if(bit_is_clear(IN, LIGHT_L)) go(FL);
   }

   return(0);
}

//------------------------------------------------------------------------------
// Главная программа
//------------------------------------------------------------------------------
int main(void)
{
 
  DDRB  = 0xff;  // назначаем все линии порта B на выход
  PORTB = 0x00;  // и устанавливаем на них низкий уровень

  DDRD  = 0x00;  // назначаем все линии порта D на вход
  PORTD = 0xff;  // подключаем внутренние нагрузочные резисторы
  //на PD2 стоит ИК приемник
  DDRB |=_BV(PB1);//ИК светодиод
       

  // запускаем главный цикл
  while(1) walk();

}

Прошу указать на мои ошибки. И вообще, я на правильном пути?

Re: Подключение ИК локатора

Vooon » 14 апр 2008, 01:30

откомментирую исходник, //<- (.*)$
Код: Выделить всёРазвернуть
#include <inttypes.h>
#include <avr/io.h>
#include <avr/signal.h> //<- выкинуть!
#include <avr/interrupt.h>
#include <stdlib.h>
#include<avr/io.h> //<- зачем два раза то включать, тем более пробел где?
#include<avr/delay.h> //<- <util/delay.h>
#define time 1.157407407//время задержки //<- лучше отказаться

// назначение определений для удобства работы с периферией
#define OUT PORTB //<- может дать более осмысленные имена?
#define MOTOR_F      PB5
#define MOTOR_B      PB3
#define TURN_L      PB4
#define TURN_R      PB2

#define IN PIND //<- см. выше
#define LIGHT_R  PD0
#define LIGHT_L  PD1
#define BUMPER_F PD3


#define sbi(port,bit)  port |=  (1<<(bit))
#define cbi(port,bit)  port &= ~(1<<(bit))
#define outb(port,bit)  port = bit //<- отказаться!

// Возможные режимы движения
enum {STOP, F, FR, FL, B, BR, BL};

//------------------------------------------------------------------------------
// Задержка t х 10ms
//------------------------------------------------------------------------------
#define F_CPU 4000000 //<- задать это ключем при компиляции -DF_CPU=4000000UL
#define K_DELAY_10ms   F_CPU/600
void Delay_10ms(unsigned char t) { //<- зачем если есть <util/delay.h> ?
  unsigned int i;
  if (t==0) return;
  while (t--) for(i=0;i<K_DELAY_10ms; i++);
}

// таблица вероятностей для выбора направления движения
// исходя из текущего направления движения
unsigned char p[7][7] = {
{14,43,   57,   71, 7, 100, 100},
{7,   43,   71,   100,100,100,100},
{7,   50,   93,   100,100,100,100},
{7,   50,   57,   100,100,100,100},
{29,29,   29,   29,   57,   79,  100},
{36,36,   36,   36,   71,   93,    100},
{36,36,   36,   36,   71,   79,    100},
};


// текущее направление движения
unsigned char this_move;

//------------------------------------------------------------------------------
// Включение комбинации моторов для движения в заданном направлении
//------------------------------------------------------------------------------
void go(unsigned char direction){

  switch (direction) {
   case STOP:
    cbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case F:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FR:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FL:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;

  case B:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BR:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BL:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;
  }
}

//------------------------------------------------------------------------------
// Выбор направления движения в следующем шаге по таблице вероятностей
//------------------------------------------------------------------------------
unsigned char next_move(void){
   unsigned char pp, i;

   pp = rand()/327;     // получаем случайное число 0..99
   for (i=0;i<7;i++){   // ищем соответствие в таблице вероятностей
      if (p[this_move][i] > pp) break;
   }
   this_move = i;       // записываем новое полученное направление как текущее
   return(i);
}






//------------------------------------------------------------------------------
// "Случайное блуждание" //<- может стоит использовать формат doxygen?
//------------------------------------------------------------------------------
unsigned char walk(void){
   // этот цикл организует "свободное блуждание" пока
   // нет сигнала ни от одного из датчиков освещенности
   while((bit_is_set(IN, LIGHT_R)) && (bit_is_set(IN, LIGHT_L))){
       go(next_move());   // получаем следующее направление движения и
       Delay_10ms(250);
} //<- плохо форматирован код, не буду проверять пока код не станет менее спагеттиобразным
   int i;
for(i=0;i<10;i++){
_delay_loop_1(time);
PORTB&=~_BV(PB1);//включаем ИК светодиод
_delay_loop_1(time);
PORTB|=_BV(PB1);//выкл Ик светодиод
}
   int u;
for(u=0;u<14;u++){
int count;
count=0;
if(bit_is_clear(PIND,PD1)){//если есть сигнал на Ик приемнике
count++;
if(count==14) {
   if(this_move==FR) go(BL);
   if(this_move==FL) go(BR);
   else go(B);
   Delay_10ms(2000);   
   Delay_10ms(2000);
   this_move=B;
}
}
}
   // этот цикл организует движение на свет, пока
   // есть сигнал хотя бы от одного из датчиков освещенности
   while((bit_is_clear(IN, LIGHT_R)) || (bit_is_clear(IN, LIGHT_L))){
       if((bit_is_clear(IN, LIGHT_R)) && (bit_is_clear(IN, LIGHT_L))) go(F);
       else if(bit_is_clear(IN, LIGHT_R)) go(FR);
       else if(bit_is_clear(IN, LIGHT_L)) go(FL);
   }

   return(0);
}

//------------------------------------------------------------------------------
// Главная программа
//------------------------------------------------------------------------------
int main(void)
{
//<- и вот смысл было вверху определять IN, OUT?
  DDRB  = 0xff;  // назначаем все линии порта B на выход
  PORTB = 0x00;  // и устанавливаем на них низкий уровень

  DDRD  = 0x00;  // назначаем все линии порта D на вход
  PORTD = 0xff;  // подключаем внутренние нагрузочные резисторы
  //на PD2 стоит ИК приемник
  DDRB |=_BV(PB1);//ИК светодиод
       

  // запускаем главный цикл
  while(1) walk(); //<- смысл выносить в отдельную функцию? или хотябы __attribute__((inline)) (если не ошибаюсь, а лучше компилить в режиме C++) добавить в описание.

}

Re: Подключение ИК локатора

Montoya » 17 апр 2008, 21:04

Спасибо большое! Вот частично поправил код, с остальным так и не разобрался.... :cry:
Так как я тормоз, прошу не ругаться...
Код: Выделить всёРазвернуть
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>
#define time 1.157407407//время задержки //<- лучше отказаться

// назначение определений для удобства работы с периферией
#define OUT PORTB //<- может дать более осмысленные имена?
#define MOTOR_F      PB5
#define MOTOR_B      PB3
#define TURN_L      PB4
#define TURN_R      PB2

#define IN PIND //<- см. выше
#define LIGHT_R  PD0
#define LIGHT_L  PD1
#define BUMPER_F PD3


#define sbi(port,bit)  port |=  (1<<(bit))
#define cbi(port,bit)  port &= ~(1<<(bit))
#define outb(port,bit)  port = bit //<- отказаться! <-Почему?

// Возможные режимы движения
enum {STOP, F, FR, FL, B, BR, BL};

//------------------------------------------------------------------------------
// Задержка t х 10ms
//------------------------------------------------------------------------------
#define F_CPU 4000000 //<- задать это ключем при компиляции -DF_CPU=4000000UL , это впринципе можно и так оставить?


// таблица вероятностей для выбора направления движения
// исходя из текущего направления движения
unsigned char p[7][7] = {
{14,43,   57,   71, 7, 100, 100},
{7,   43,   71,   100,100,100,100},
{7,   50,   93,   100,100,100,100},
{7,   50,   57,   100,100,100,100},
{29,29,   29,   29,   57,   79,  100},
{36,36,   36,   36,   71,   93,    100},
{36,36,   36,   36,   71,   79,    100},
};


// текущее направление движения
unsigned char this_move;

//------------------------------------------------------------------------------
// Включение комбинации моторов для движения в заданном направлении
//------------------------------------------------------------------------------
void go(unsigned char direction){

  switch (direction) {
   case STOP:
    cbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case F:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FR:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case FL:
    sbi(OUT, MOTOR_F);
    cbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;

  case B:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BR:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    sbi(OUT, TURN_R);
    cbi(OUT, TURN_L);
    break;

  case BL:
    cbi(OUT, MOTOR_F);
    sbi(OUT, MOTOR_B);
    cbi(OUT, TURN_R);
    sbi(OUT, TURN_L);
    break;
  }
}

//------------------------------------------------------------------------------
// Выбор направления движения в следующем шаге по таблице вероятностей
//------------------------------------------------------------------------------
unsigned char next_move(void){
   unsigned char pp, i;

   pp = rand()/327;     // получаем случайное число 0..99
   for (i=0;i<7;i++){   // ищем соответствие в таблице вероятностей
      if (p[this_move][i] > pp) break;
   }
   this_move = i;       // записываем новое полученное направление как текущее
   return(i);
}






//------------------------------------------------------------------------------
// "Случайное блуждание" //<- может стоит использовать формат doxygen? <-Почитал об этом в нете и нифиа не понял.....
//------------------------------------------------------------------------------
unsigned char walk(void){
   // этот цикл организует "свободное блуждание" пока
   // нет сигнала ни от одного из датчиков освещенности
   while((bit_is_set(IN, LIGHT_R)) && (bit_is_set(IN, LIGHT_L))){
       go(next_move());   // получаем следующее направление движения и
       delay_ms(2500); 
} //<- плохо форматирован код, не буду проверять пока код не станет менее спагеттиобразным
   int i;
   for(i=0;i<10;i++){
      _delay_loop_1(time);
      PORTB&=~_BV(PB1);//включаем ИК светодиод
      _delay_loop_1(time);
      PORTB|=_BV(PB1);//выкл Ик светодиод
   }
   
   int u;
   for(u=0;u<14;u++){
      int count;
      count=0;
      if(bit_is_clear(PIND,PD1)){//если есть сигнал на Ик приемнике
         count++;
         if(count==14) {
             if(this_move==FR) go(BL);
             if(this_move==FL) go(BR);
             else go(B);
             delay_ms(2500);   
             delay_ms(2500);
             this_move=B;
         }
      }
   }
   // этот цикл организует движение на свет, пока
   // есть сигнал хотя бы от одного из датчиков освещенности
   while((bit_is_clear(IN, LIGHT_R)) || (bit_is_clear(IN, LIGHT_L))){
       if((bit_is_clear(IN, LIGHT_R)) && (bit_is_clear(IN, LIGHT_L))) go(F);
       else
         if(bit_is_clear(IN, LIGHT_R)) go(FR);
         else
           if(bit_is_clear(IN, LIGHT_L)) go(FL);
   }

   return(0);
}

//------------------------------------------------------------------------------
// Главная программа
//------------------------------------------------------------------------------
int main(void)
{
//<- и вот смысл было вверху определять IN, OUT?так там OUT и IN это произвольные названия, закрепленные за всеми портами,вроде...
  DDRB  = 0xff;  // назначаем все линии порта B на выход
  PORTB = 0x00;  // и устанавливаем на них низкий уровень

  DDRD  = 0x00;  // назначаем все линии порта D на вход
  PORTD = 0xff;  // подключаем внутренние нагрузочные резисторы
  //на PD2 стоит ИК приемник
  DDRB |=_BV(PB1);//ИК светодиод
       

  // запускаем главный цикл
  while(1) walk(); //<- смысл выносить в отдельную функцию? или хотябы __attribute__((inline)) (если не ошибаюсь, а лучше компилить в режиме C++) добавить в описание. Это мне совсем не понятно....

}

Re: Подключение ИК локатора

Vooon » 18 апр 2008, 11:32

выправил стиль
теперь осталось переписать ик бампер

для чего doxygen смотри ./doc/dist/html/index.html
Вложения
Montoya.tar.bz2
(73.48 КиБ) Скачиваний: 47

Re: Подключение ИК локатора

Montoya » 20 апр 2008, 14:20

Хы, круто!
Значит мне надо переделать вот этот кусок кода? Или у меня неправильная только та часть,которая отвечает за прием сигнала?
Код: Выделить всёРазвернуть
  for (int i=0; i < 10; i++) {
        _delay_loop_1(TIME);
        CBI(PORTOUT, IRLED);    // включаем ИК светодиод
        _delay_loop_1(TIME);
        SBI(PORTOUT, IRLED);    // выкл ИК светодиод
    }
   
    for (int u=0; u < 14; u++){
        int count=0;
        // если есть сигнал на Ик приемнике
        if (bit_is_clear(PININ, LIGHT_L)) { //только здесь должно быть не LIGHT_L, а BUMPER_F - т.е. TSOP
            count++;
            if (count == 14) {
                if (this_move == FR)
                    go(BL);
                if (this_move == FL)
                    go(BR);
                else
                    go(B);
               
                // дай угадаю, не работает?
                delay_ms(2500);
                delay_ms(2500);
               
                this_move = B;
            }
        }
    }


Добавлено спустя 13 минут 21 секунду:
Вот переделал приемную часть. Единственное что я нашел из ошибок, так это то, что счетчик все время обнулялся...
Код: Выделить всёРазвернуть
int count=0;
for (int u=0; u < 14; u++){
        // если есть сигнал на Ик приемнике
        if (bit_is_clear(PININ, BUMPER_F)) {             
            count++;
            if (count == 14) {
                if (this_move == FR)
                    go(BL);
                if (this_move == FL)
                    go(BR);
                else
                    go(B);
               
                // дай угадаю, не работает?
                delay_ms(2500);
                delay_ms(2500);
               
                this_move = B;
            }
        }
    }
Последний раз редактировалось Montoya 20 апр 2008, 14:30, всего редактировалось 1 раз.


Rambler\'s Top100 Mail.ru counter