roboforum.ru

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

 

GP2D120

Обсуждение и примеры готовых и самосборных компонент для построения роботов.

GP2D120

Сообщение gambit6 » 07 сен 2005, 17:55

Вот доставили мне сегодня заказ с робоклуба.
У меня в сборе имеется процессорная плата как в проекте
"делаем робота вместе". Вопрос такой, как работают датчики?
2 из проводов  это я так понимаю питание, а 3 это логика?
Он должен выдавать логическую единицу или ноль?
Как работает сам датчик, кто подскажет?
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение setar » 08 сен 2005, 12:45

Аватара пользователя
setar
Site Admin
 
Сообщения: 9257
Зарегистрирован: 04 окт 2004, 12:58
Откуда: St.Petersburg
Skype: taranenko.sergey
ФИО: Сергей Тараненко

Сообщение gambit6 » 08 сен 2005, 23:26

Ну, да... понятно, а как вообще программу писать?
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение -= Александр =- » 08 сен 2005, 23:37

Если я правильно помню - выход у него аналоговый... Так что юзай АЦП. Подключаешь его к аналоговому входу, а в программе запускаешь АЦП. Как это делать зависит от того в чем ты пишешь, в сети есть куча примеров, ищи...
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

Сообщение gambit6 » 12 сен 2005, 22:40

Хорошо, датчик расчитан на 30 см, а мне допустим надо чтоб робот реагировал на препятствие около 5 см. Как это сделать?
Пишу я на AVRedit 3.5 программа такая же как на робоклубе в проекте "Делаем робота вместе", за исключением системы поворотов, но это рояля не играет... Бамперы (механические) сейчас висят на int1 и int0. Есть два датчика Шарповских GP2D12, очень хочется заменить бамперы на датчики. Кто что посоветует?
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение Kanoka » 12 сен 2005, 23:57

Дык все таки 12-ый или 120-ый?

GP2D12 на 5 сантиметров не видит, на растоянии меньше 8 см теряет сигнал. Ну не суть, если использовать их вместо бамперов то больше подойдут цифровые, они срабатывают в некой точке Х, тобиш переключаются с 0 на 1.

Например у GP2D15 эта точка Х находится на растоянии 24 см.
Kanoka
Модератор
 
Сообщения: 1271
Зарегистрирован: 11 ноя 2004, 03:18
Откуда: Москва

Сообщение gambit6 » 13 сен 2005, 16:44

GP2D120. Другого, к сожалению нет... :(
Канока, с 15 все понятно, а как с этим быть?
Разве он будет реагировать только на 30 см?
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение Kanoka » 13 сен 2005, 20:36

Разве он будет реагировать только на 30 см?

Будет и дальше, но с очень маленьким напряжением на выходе (30см - 0.42V, 40см - 0.3V...)

с 15 все понятно, а как с этим быть?

Попробуй поменяться с Сетаром, у него помоему есть парочка 15-х :)
Kanoka
Модератор
 
Сообщения: 1271
Зарегистрирован: 11 ноя 2004, 03:18
Откуда: Москва

Сообщение setar » 14 сен 2005, 15:11

Kanoka писал(а):Попробуй поменяться с Сетаром, у него помоему есть парочка 15-х :)

точно у меня есть пара, могу штучкой для коллекции поменяться, пока никуда не прикручивал.
Аватара пользователя
setar
Site Admin
 
Сообщения: 9257
Зарегистрирован: 04 окт 2004, 12:58
Откуда: St.Petersburg
Skype: taranenko.sergey
ФИО: Сергей Тараненко

Сообщение gambit6 » 15 сен 2005, 21:09

Народ, подскажите, как дописать прогу под GP2D120?
Датчики подключил к портам PD4  и PD5.
Пишу, точнее редактирую прогу с сайта робоклуба на AVRedit...
Ниже идет сама прога... Плиз помогите уже 2 недели мучаюсь...
Хотелось бы чтоб датчики хоть как то заработали, пусть даже на 30 см,
конечно хотелось бы на 7-8 см... но... электроника дело точное.

//------------------------------------------------------------------------
// http://WWW.Roboclub.ru "Делаем робота вместе"
// Программа уже слегка модифицирована под мою конструкцию
//------------------------------------------------------------------------

#include <inttypes.h>
#include <io.h>
#include <sig-avr.h>
#include <interrupt.h>
#include <stdlib.h>

// назначение определений для удобства работы с периферией
#define OUT PORTB
#define MOTOR1_F  PB7
#define MOTOR1_B  PB6
#define MOTOR2_F  PB5
#define MOTOR2_B  PB4

#define IN PIND
#define LIGHT_R  PD0   // Эти датчики вообще моей конструкцией не предусмотрены
#define LIGHT_L  PD1
#define BUMPER_F PD2   //   Это порты для механических бамперов, полагаю их
#define BUMPER_B PD3   //   лучше вообще убрать, или для другого устройства приспособить.

// Возможные режимы движения
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, 86, 57, 71, 43, 93, 100},
{7, 100, 71, 100, 43, 100, 100},
{7, 100, 93, 100, 50, 100, 100},
{7, 100, 57, 100, 50, 100, 100},
{29, 57, 29, 29, 29, 79, 100},
{36, 71, 36, 36, 36, 93, 100},
{36, 71, 36, 36, 36, 79, 100},
};

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

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

 switch (direction) {
 case STOP:
   cbi(OUT, MOTOR1_F);
   cbi(OUT, MOTOR1_B);
   cbi(OUT, MOTOR2_F);
   cbi(OUT, MOTOR2_B);
   break;

 case F:
   sbi(OUT, MOTOR1_F);
   cbi(OUT, MOTOR1_B);
   sbi(OUT, MOTOR2_F);
   cbi(OUT, MOTOR2_B);
   break;

 case FR:
   cbi(OUT, MOTOR1_F);
   cbi(OUT, MOTOR1_B);
   sbi(OUT, MOTOR2_F);
   cbi(OUT, MOTOR2_B);
   break;

 case FL:
   sbi(OUT, MOTOR1_F);
   cbi(OUT, MOTOR1_B);
   cbi(OUT, MOTOR2_F);
   cbi(OUT, MOTOR2_B);
   break;

 case B:
   cbi(OUT, MOTOR1_F);
   sbi(OUT, MOTOR1_B);
   cbi(OUT, MOTOR2_F);
   sbi(OUT, MOTOR2_B);
   break;

 case BR:
   cbi(OUT, MOTOR1_F);
   cbi(OUT, MOTOR1_B);
   cbi(OUT, MOTOR2_F);
   sbi(OUT, MOTOR2_B);
   break;

 case BL:
   cbi(OUT, MOTOR1_F);
   sbi(OUT, MOTOR1_B);
   cbi(OUT, MOTOR2_F);
   cbi(OUT, MOTOR2_B);
   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);
}

//------------------------------------------------------------------------------
// Обработка прерывания от переднего бампера (INT0 = PD2)
//------------------------------------------------------------------------------
SIGNAL(SIG_INTERRUPT0)
{
  if(this_move==FR) go(BL);
  if(this_move==FL) go(BR);
  else go(B);
  Delay_10ms(250);    // отъезд в течение 2.5 х 2 сек
  Delay_10ms(250);
  this_move=B;
}

//------------------------------------------------------------------------------
// Обработка прерывания от заднего бампера (INT1 = PD3)
//------------------------------------------------------------------------------
SIGNAL(SIG_INTERRUPT1)
{
  if(this_move==BR) go(FL);
  if(this_move==BL) go(FR);
  else go(F);
  Delay_10ms(250);    // отъезд в течение 2.5 х 2 сек
  Delay_10ms(250);
  this_move=F;
}

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

}
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение -= Александр =- » 15 сен 2005, 22:21

Скажи частоту своего кварца - сделаю тебе кусочек кода...
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

Сообщение gambit6 » 15 сен 2005, 22:29

Кварц- 4 мегагерца, Александр очень признателен. Огромное
спасибо.
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение -= Александр =- » 15 сен 2005, 23:00

AVREdit я куда-то засунул и не могу найти. На ICC это выглядит так:

Код: Выделить всёРазвернуть
//ADC initialize
// Conversion time: 104uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0
ACSR  = 0x80;
ADCSR = $ADCSR$;
}

#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
//conversion complete, read value (int) using...
// value=ADCL;            //Read 8 low bits first (important)
// value|=(int)ADCH << 8; //read 2 high bits and shift into top byte
}
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

Сообщение gambit6 » 15 сен 2005, 23:25

Не, я конечно понимаю что ты крут  :D  Но я пока не на столько  :shock:  Вот как выглядит реакция на датчик света СВЗ-1  в этой программе:
// "Случайное блуждание"
//------------------------------------------------------------------------------
unsigned char walk(void){
 // этот цикл организует "свободное блуждание" пока
 // нет сигнала ни от одного из датчиков освещенности
 while((bit_is_set(IN, LIGHT_R)) && (bit_is_set(IN, LIGHT_L))){
     go(next_move());   // получаем следующее направление движения и
     Delay_10ms(250);   // движемся в этом направлении 2.5 сек
 }
 // этот цикл организует движение на свет, пока
 // есть сигнал хотя бы от одного из датчиков освещенности
 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);
}

Может из этого можно что-то переделать? Не охота всю прогу в ICC переписывать :(  На это еще месяцев 5 уйдет :(
Хотелось бы эту отшлифовать до совершенства.
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение -= Александр =- » 15 сен 2005, 23:34

Все дело в том что нужно не просто получить сигнал с датчика, а измерить напряжение его выхода. Для этого нужно задействовать АЦП. Как это делается на AVREdit я уже забыл, а примерчик не сохранился...  
Вот тут все рассказано: http://parts.roboclub.ru/index.shtml?adc
Так что значения дальномеров будешь читать функцией read_adc, а выбирать из какого читать тут: MUX4..0=ADC7; обычно имеется 8 каналов. К двум из них следует подключить твои датчики. В момент времени может работать только один из каналов, так что опрашивать их надо по-очереди.
Аватара пользователя
-= Александр =-
Мастер Самоделкин
 
Сообщения: 3664
Зарегистрирован: 11 окт 2004, 19:20
Откуда: Россия, СПб
прог. языки: C++, VB, asm
ФИО: Курмис Александр Андреевич

След.

Вернуться в Готовые модули

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Mail.ru counter