цифровая электроника
вычислительная техника
встраиваемые системы

 

Однопиксельная камера для Arduino своими руками

Автор: Mike(admin) от 10-10-2018, 13:15

Классические платы Arduino, вроде Arduino Uno или Arduino Nano, являются довольно простыми и не обладают мощным микроконтроллером. Благодаря этому их цена очень низка. Но иногда возникают ситуации, когда необходимо сделать проект получения простых изображений из реального мира при весьма ограниченном бюджете. Стандартные модули камер микроконтроллеры серии ATmega могут не потянуть.


Однопиксельная камера для Arduino своими руками

Но есть очень простое решение – сделать однопиксельную камеру, которая сможет последовательно сформировать изображение какого-нибудь небольшого объекта. И дешевые платы Arduino смогут справиться с этой задачей.


Для реализации камеры для Arduino используем датчик света TEPT4400 компании VISHAY. TEPT4400 представляет собой фототранзистор, способный изменять напряжение при изменении интенсивности падающего на него света. Ниже показана схема подключения датчика света к Arduino.


датчик света TEPT4400

Для того, чтобы поток света был целенаправленным, и мы могли получать четкий пиксель, накроем датчик света длинным непрозрачным цилиндром с отверстием и получим некое подобие камеры.


Однопиксельная камера для Arduino своими руками

Для того, чтобы получать не одну точку, а набор точек в плоскости пространства, установим самодельную камеру на платформу с серводвигателями, которыми будет управлять Arduino. В результате может получиться что-то вроде этого.


Однопиксельная камера для Arduino своими руками

Для получения изображения на компьютере создадим простую программу с использованием языка программирования Processing. Представленное ниже изображение состоит из матрицы 40×30 пикселей. Arduino отправляет в компьютер координаты x и y, а также интенсивность света каждой позиции. Processing просто рисует каждую точку изображения со значением в сером диапазоне 0-255.


Однопиксельная камера для Arduino своими руками

Далее приведен простой код на языке Processing для отображения полученных с камеры и Arduino данных.



import processing.serial.*;

Serial port; 

int xPos;
int yPos;
int value;

void setup(){
  println(Serial.list());               // проверка номера COM-порта
  String portName = Serial.list()[0];   // принимаем индекс порта через Serial.list[]
  port = new Serial(this, portName, 9600);
  port.bufferUntil(10); 
  size(320,240);
  background(255);
}

void draw(){

}

void serialEvent(Serial _port){
  String input = port.readString(); 
  input = trim(input);
  String[] vars = split(input, ",");
  xPos = int(vars[0]);
  yPos = int(vars[1]);
  value = int(vars[2]);

  println(value);         // чтобы увидеть полученные значения
  noStroke();
  fill(value);
  rect(xPos*8, yPos*8, 8, 8);
}

Далее приведен скетч (код) для Arduino, позволяющий принимать информацию об интенсивности света с камеры, управлять электроприводом и отправлять данные в компьютер для отображения результатов.



#include <Servo.h> 

#define TILT_SERVO  7
#define PAN_SERVO   8

#define H_SIZE      40   // Горизонтальные элементы изображения
#define V_SIZE      30   // Вертикальные элементы изображения
#define SENSOR      0    // Датчик интенсивности света
#define Xcenter     140  // Центр изображения X (положение сервопривода в градусах)
#define Ycenter     35   // Центр изображения Y (положение сервопривода в градусах)

//-------------------------------------
// Определения и переменные, используемые функцией ReadPixel()
#define AnalogIn    0
#define Tcharge1    5000    // Задержка в микросекундах перед первым считыванием
#define Tcharge2    20000   // Задержка в микросекундах перед вторым считыванием

// Макросы для управления схемой датчика света
#define Discharge  {DDRD &= B00000011; DDRD |= B00001000; PORTD |= B00000000;}  // выход D3 в 0
#define Sense      {DDRD &= B00000011; DDRD |= B00000000; PORTD |= B00000000;}  //D3 в качестве входной линии

// Переменные
int first,second;

//-------------------------------------
Servo servo_tilt;
Servo servo_pan;

//------------------------------------- Функции
//---------------------------------------------------------------------
void SendPixel(int xPos, int yPos, int value){
   Serial.print(xPos); Serial.print(","); Serial.print(yPos); Serial.print(","); Serial.println(value); 
}

//--------------------------------------------------------------------- 
void goto_origin(){
  servo_tilt.write( V_SIZE/2 + Ycenter ); // Наклон сервомотора вверх
  servo_pan.write( Xcenter - H_SIZE/2 );  // Сдвиг сервомотора влево
  delay(1000);                            // время достижения цели
}

//--------------------------------------------------------------------- 
int ReadPixel(){
delayMicroseconds(Tcharge1);    // Задержка для получения первого значения
first= analogRead(AnalogIn);    // первое значение получено
delayMicroseconds(Tcharge2);    // Задержка для получения второго значения
second= analogRead(AnalogIn);   // второе значение получено
if (first<200)first= second;    // если первое меньше 200, второе будет меньше 1024
else first = first * 5 ;        // если первое более 200, будет использоваться первое * 5
first = map(first, 0, 60, 0, 255); // карта была скорректирована для условий освещения
return first;
}

//------------------------ настройка 
void setup() 
{ 
  servo_tilt.attach(TILT_SERVO); 
  servo_pan.attach(PAN_SERVO);
  Serial.begin(9600);

  ReadPixel();      // Прочитать и отбросить (для следующего чтения).
} 

//-------------------------- бесконечный цикл 
void loop(){

  goto_origin();

  for (int y=0 ; y<V_SIZE ; y++) { 

    servo_tilt.write(Ycenter + V_SIZE/2 -y );
    delay(50);                              // время достижения позиции

     for ( int x=0 ; x<H_SIZE ; x++) {      // Сканирование слева на право
      servo_pan.write(Xcenter - H_SIZE/2 + x);
      delay(50);                            // время достижения позиции

      SendPixel(x, y, ReadPixel());      
    }
    y++;
    servo_tilt.write(Ycenter + V_SIZE/2 - y);
    delay(50);                              // время достижения позиции

      for ( int x=H_SIZE-1 ; x>=0 ; x--) {  // Сканирование справа на лево
      servo_pan.write(Xcenter - H_SIZE/2 + x);     
      delay(50);                            // время достижения позиции

      SendPixel(x, y, ReadPixel());
    }

  }
}



© digitrode.ru


Теги: Arduino, камера




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

Комментарии:

Оставить комментарий