'Arduino'에 해당되는 글 2건

  1. 2015.03.07 RC Car #1 (1)
  2. 2015.03.03 아두이노로 만든 LED 사인 - LED Matrix 8x8

이번에는 적외선 센서를 이용한 자동차 원격 조정입니다.



완제품 형태도 있지만, 모터 드라이버 등을 따로 구매해서 제작하였습니다.  덕분에 너트로 붙이지 못하고, 스카치 테입으로 고정하여 쓰고 있습니다.


소스 코드가 어려워서 일단 라이브러 레벨에서는 준비해주고, 동작 설명을 한 다음, setup()과 loop()만을 완성하도록 하였습니다.  역시나 너무 어려우면 흥미를 잃어 버릴 것이 걱정이 되서요 ^^;


일단 건전지를 다 쓸 때까지 신나게 노는 군요 ^^*


아두이노 보드 뒷 면에 핀을 납땜해서 붙였습니다.  모터 드라이버를 끼고 나면 안쓰는 핀을 꼽을 수가 없어서, 적외선 센서를 달 수가 없었기 때문입니다.


다음에는 바퀴 네 개 짜리를 테스트 해봐야 할 것 같습니다.  뒤에 있는 하나 짜리 바퀴가 제 자리를 잘 찾지 못하고, 바퀴의 품질 문제로 약간 옆으로 휘어서 가는 문제가 있습니다.  






사용한 부품




소스 코드

#include <IRremote.h>

#define MOTORCLK 4
#define MOTORENABLE 7
#define MOTORDATA 8
#define MOTORLATCH 12

#define MOTOR1_A 2
#define MOTOR1_B 3
#define MOTOR2_A 1
#define MOTOR2_B 4
#define MOTOR3_A 5
#define MOTOR3_B 7
#define MOTOR4_A 0
#define MOTOR4_B 6

// Arduino pins for the PWM signals.
#define MOTOR1_PWM 11
#define MOTOR2_PWM 3
#define MOTOR3_PWM 6
#define MOTOR4_PWM 5
#define SERVO1_PWM 10
#define SERVO2_PWM 9

// Codes for the motor function.
#define FORWARD 1
#define BACKWARD 2
#define BRAKE 3
#define RELEASE 4

// 방향키 설정
#define UP_KEY 0xFD8877
#define DOWN_KEY 0xFD9867
#define LEFT_KEY 0xFD28D7
#define RIGHT_KEY 0xFD6897
#define OK_KEY 0xFDA857
#define STAR_KEY 0xFD30CF
#define SHARP_KEY 0xFD708F

int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
	irrecv.enableIRIn();
}

void loop() {
	if (irrecv.decode(&results)) {
		if (results.value == UP_KEY) {
			motor_output(MOTOR3_A, HIGH, 255);
			motor_output(MOTOR3_B, LOW, -1);
			motor_output(MOTOR4_A, HIGH, 255);
			motor_output(MOTOR4_B, LOW, -1);
		}
		else if (results.value == DOWN_KEY) {
			motor_output(MOTOR3_A, LOW, -1);
			motor_output(MOTOR3_B, HIGH, 255);
			motor_output(MOTOR4_A, LOW, -1);
			motor_output(MOTOR4_B, HIGH, 255);
		}
		else if (results.value == LEFT_KEY) {
			motor_output(MOTOR3_A, HIGH, 150);
			motor_output(MOTOR3_B, LOW, -1);
			motor_output(MOTOR4_A, HIGH, 255);
			motor_output(MOTOR4_B, LOW, -1);
		}
		else if (results.value == RIGHT_KEY) {
			motor_output(MOTOR3_A, HIGH, 255);
			motor_output(MOTOR3_B, LOW, -1);
			motor_output(MOTOR4_A, HIGH, 150);
			motor_output(MOTOR4_B, LOW, -1);
		}
		else if (results.value == OK_KEY) {
			motor_output(MOTOR3_A, LOW, -1);
			motor_output(MOTOR3_B, LOW, -1);
			motor_output(MOTOR4_A, LOW, -1);
			motor_output(MOTOR4_B, LOW, -1);
		}
		else if (results.value == STAR_KEY) {
			motor_output(MOTOR3_A, LOW, -1);
			motor_output(MOTOR3_B, HIGH, 255);
			motor_output(MOTOR4_A, HIGH, 255);
			motor_output(MOTOR4_B, LOW, -1);
		}
		else if (results.value == SHARP_KEY) {
			motor_output(MOTOR3_A, HIGH, 255);
			motor_output(MOTOR3_B, LOW, -1);
			motor_output(MOTOR4_A, LOW, -1);
			motor_output(MOTOR4_B, HIGH, 255);
		}

		irrecv.resume();
	}
}

void motor_output(int output, int high_low, int speed) {
	int motorPWM;

	switch (output) {
	case MOTOR1_A:
	case MOTOR1_B:
		motorPWM = MOTOR1_PWM;
		break;
	case MOTOR2_A:
	case MOTOR2_B:
		motorPWM = MOTOR2_PWM;
		break;
	case MOTOR3_A:
	case MOTOR3_B:
		motorPWM = MOTOR3_PWM;
		break;
	case MOTOR4_A:
	case MOTOR4_B:
		motorPWM = MOTOR4_PWM;
		break;
	default:
		// Use speed as error flag, -3333 = invalid output.
		speed = -3333;
		break;
	}

	if (speed != -3333) {
		// Set the direction with the shift register
		// on the MotorShield, even if the speed = -1.
		// In that case the direction will be set, but
		// not the PWM.
		shiftWrite(output, high_low);

		// set PWM only if it is valid
		if (speed >= 0 && speed <= 255) {
			analogWrite(motorPWM, speed);
		}
	}
}

void shiftWrite(int output, int high_low) {
	static int latch_copy;
	static int shift_register_initialized = false;

	// Do the initialization on the fly,
	// at the first time it is used.
	if (!shift_register_initialized) {
		// Set pins for shift register to output
		pinMode(MOTORLATCH, OUTPUT);
		pinMode(MOTORENABLE, OUTPUT);
		pinMode(MOTORDATA, OUTPUT);
		pinMode(MOTORCLK, OUTPUT);

		// Set pins for shift register to default value (low);
		digitalWrite(MOTORDATA, LOW);
		digitalWrite(MOTORLATCH, LOW);
		digitalWrite(MOTORCLK, LOW);
		// Enable the shift register, set Enable pin Low.
		digitalWrite(MOTORENABLE, LOW);

		// start with all outputs (of the shift register) low
		latch_copy = 0;

		shift_register_initialized = true;
	}

	// The defines HIGH and LOW are 1 and 0.
	// So this is valid.
	bitWrite(latch_copy, output, high_low);

	// Use the default Arduino 'shiftOut()' function to
	// shift the bits with the MOTORCLK as clock pulse.
	// The 74HC595 shiftregister wants the MSB first.
	// After that, generate a latch pulse with MOTORLATCH.
	shiftOut(MOTORDATA, MOTORCLK, MSBFIRST, latch_copy);
	delayMicroseconds(5); // For safety, not really needed.
	digitalWrite(MOTORLATCH, HIGH);
	delayMicroseconds(5); // For safety, not really needed.
	digitalWrite(MOTORLATCH, LOW);
}



Posted by 류종택
TAG Arduino


  • 아이가 가지고 다닐 수 있도록 2mm 하드보드지를 이용하여 박스를 제작하였습니다.
  • 폰트 및 박스 제작은 아이에게 맡기고, 납땜 작업을 제가 도와 주었습니다.  코딩은 폰트 부분만 변경 할 수 있도록 미리 준비하고, 나머지는 간략하게 설명하는 것으로 마쳤습니다.  너무 어려워서 지치면 흥미를 잃을 까봐 ^^;
  • 크기를 줄이기 위해서 ATTiny 85 칩을 이용해서 만들었습니다.



사용한 부품



소스 코드

#include <avr/pgmspace.h>

int Max7219_pinCLK = 2;
int Max7219_pinCS = 1;
int Max7219_pinDIN = 0;

void Write_Max7219_byte(unsigned char DATA) {
	digitalWrite(Max7219_pinCS, LOW);
	for (int i = 8; i >= 1; i--) {
		digitalWrite(Max7219_pinCLK, LOW);
		digitalWrite(Max7219_pinDIN, DATA&0x80);
		DATA = DATA << 1;
		digitalWrite(Max7219_pinCLK, HIGH);
	}
}

void Write_Max7219(unsigned char address, unsigned char dat) {
	digitalWrite(Max7219_pinCS, LOW);
	Write_Max7219_byte(address);
	Write_Max7219_byte(dat);
	digitalWrite(Max7219_pinCS, HIGH);
}

void Init_MAX7219(void) {
	Write_Max7219(0x09, 0x00);
	Write_Max7219(0x0a, 0x03);
	Write_Max7219(0x0b, 0x07);
	Write_Max7219(0x0c, 0x01);
	Write_Max7219(0x0f, 0x00);
}

const int lines = 6;

const unsigned char disp1[lines][8] PROGMEM = {
      { 0x72, 0x8A, 0x8A, 0x73, 0x02, 0x42, 0x40, 0x7E },
      { 0x81, 0x87, 0x81, 0xF7, 0x01, 0x39, 0x44, 0x38 },
      { 0x32, 0x02, 0x7A, 0x03, 0x32, 0x4A, 0x4A, 0x32 },
      { 0x25, 0x25, 0x25, 0x2D, 0x65, 0x95, 0x95, 0x95 },
      { 0x3C, 0x42, 0x42, 0x3C, 0x00, 0x24, 0x24, 0xFF },
      { 0x3C, 0x42, 0x42, 0x02, 0x0C, 0x10, 0x00, 0x10 }
};

void setup() {
	pinMode(Max7219_pinCLK, OUTPUT);
	pinMode(Max7219_pinCS, OUTPUT);
	pinMode(Max7219_pinDIN, OUTPUT);
	delay(500);
	Init_MAX7219();
}

void loop() {
	for (int j = 0; j < lines; j++) {
		for (int i = 1; i < 9; i++)
			Write_Max7219(i, pgm_read_byte(&disp1[j][i - 1]));
		delay(500);
	}
}

32-40: 라인만 수정하시면 원하시는 그림이나 문자를 화면에 표시 할 수 있습니다.




Dot Matrix Editor


위의 도트 폰트를 제작 할 때 사용하기 위해 만든 프로그램과 소스 입니다.

유닛 하나가 필요하네요. (https://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/Strg.pas)


Dot Matrix Editor.zip


  • Ctrl 키를 누르고 있는 상태에서는 마우스가 지나가는 LED 마다 불이 켜집니다.
  • 왼쪽 Shift 키를 누르고 있는 상태에서는 마우스가 지나가는 LED 마다 불이 꺼집니다.
  • LED를 클릭하면 불이 켜졌다 꺼졌다를 반복합니다.
  • 완성 된 글자는 Add 버턴을 클릭하면, 완성 된 폰트 데이터(문자열)이 화면에 추가 됩니다.
  • 모두 완성 되면, Play 버턴을 클릭하여 확인합니다.
  • 소스 코드 35-40: 라인에 덮어 쓰시고, 작성하신 라인(폰트) 수를 32: 라인의 lines에 입력합니다.
  • 아두이노에 스케치를 업로드하시면 작업이 완료됩니다.



하드보드지 도면


LED Matrix 8x8.pdf


  • 하드보드지에 붙여놓고 칼로 자른 다음 조각들을 스카치 테잎을 이용해서 붙여서 사용했습니다.
    • 하드보드지를 한 번에 자르는 것은 힘이 듭니다.  아이가 작업하다가 칼이 미끄러져 다칠 뻔 한 일이 있었습니다.  처음에는 줄을 긋는다고 생각하고 살며시 그으면 칼이 파여진 홈에 따라서 잘 미끄러지지 않게 됩니다.  그 이후에도 욕심 내지 않고 여러 번 천천히 칼을 그어서 잘라내면 됩니다.
    • 가위를 사용하셔도 됩니다.  칼보다는 덜 이쁘게 나오는 것만 빼면 문제 없습니다.








Posted by 류종택
TAG Arduino