'전동차 개조'에 해당되는 글 3건
- 2015.06.12 콘트롤러를 제작하다 #1 1
- 2015.06.11 컨트롤용 보드용 코드를 짜다.
- 2015.06.11 자작 조종기를 살리다.
콘트롤러를 제작하다 #1
자작 송신기 - 수신기 - 아두이노 - 인버터 - 모터
궁극적으로는
스마트폰 <-> 블루투스 - 아두이노 - 인버터 - 모터
를 생각하고 있지만 안드로이드 앱을 제작해본적이 없어서 이것은 뒤로 미루고 있습니다.
(안드로이드 개발 관련 AIDE 라고 기가막힌 앱이 있더군요. 이걸 좀 볼까 합니다)
어쨌든, 수신기에서 나오는 시그널을 아두이노에서 잘 받아들이는지 확인하기 위해서, 보드를 땜질하고 간단하게 코딩을 하여 확인을 했습니다.
컨트롤용 보드용 코드를 짜다.
#include <Wire.h>
#include <EEPROM.h>
#include <pins_arduino.h>
#define MOTOR_1 (3)
#define MOTOR_2 (9)
#define MOTOR_3 (10)
#define MOTOR_4 (11)
//PIN assignment
#define CHANNEL_NUM (3) // use ar7000 satelite receiver - spektrum
#define THROTTLEPIN (2)
#define STEERPIN (4)
#define AUXPIN (5)
#define RECIEVER_SENSITIVITY (10)
#define MOTOR_SENSITIVITY (10)
int16_t rcCommand1 = 0;
int16_t rcCommand2= 0;
int16_t rcCommand3= 0;
int16_t rcCommand4 =0;
uint8_t pinRcChannel[3] = {THROTTLEPIN,STEERPIN,AUXPIN};
uint8_t PCintLast = 0;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// main loop
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
uint32_t previousTime = 0;
uint32_t currentTime = 0;
uint32_t deltaTime = 0;
uint32_t meanTime = 0;
uint32_t rcTime = 0;
uint8_t armed = 0;
short commandFilter(short old_val, short new_val)
{
short ret;
ret = constrain(new_val,old_val-RECIEVER_SENSITIVITY,old_val+RECIEVER_SENSITIVITY);
return ret;
}
short MotorFilter(short old_val,short new_val) {
short ret;
ret= constrain(new_val,old_val-MOTOR_SENSITIVITY,old_val+MOTOR_SENSITIVITY);
return ret;
}
typedef struct {
uint16_t edgeTime;
int16_t Width;
} pinTimingData;
pinTimingData pin1;
pinTimingData pin2;
pinTimingData pin3;
pinTimingData pin4;
SIGNAL(PCINT2_vect) {
uint8_t mask;
uint16_t cTime;
uint16_t temp;
cTime = micros();
mask = PIND ^ PCintLast;
PCintLast = PIND;
// mask is pins [D0-D7] that have changed.
// chan = pin sequence of the port. chan begins at D2 and ends at D5
// because we are here, at least one pin [D2-D5] changed
// avoiding a for() is more than twice faster !
if (mask & (1<<THROTTLEPIN)) {
if (!(PIND & 0x01 << THROTTLEPIN)) temp = cTime - pin1.edgeTime;
pin1.Width = (int16_t)(temp - 1120); // minimum throttle
pin1.edgeTime = cTime;
}
if (mask & (1<<STEERPIN)) {
if (!(PIND & 0x01 << STEERPIN)) temp = cTime - pin2.edgeTime;
pin2.Width = (int16_t)(temp - 1500);
pin2.edgeTime = cTime;
}
if (mask & (1<<AUXPIN)) {
if (!(PIND & 0x01 << AUXPIN)) temp = cTime - pin3.edgeTime;
pin3.Width = (int16_t)(temp - 1500);
pin3.edgeTime = cTime;
}
}
// Configure each rc pin for PCINT
void configureReceiver() {
uint8_t chan;
PCMSK2 = 0;
for (chan=0; chan < 4; chan++) {
pinMode(pinRcChannel[chan], INPUT);
// PCINT activated only for specific pin inside [D0-D7] , [D2-D5] for this tricopter
PCMSK2 |= digitalPinToBitMask(pinRcChannel[chan]);
}
PCICR = 0x01 << 2; // PCINT activated only for [D0-D7] port
}
void setup() {
pinMode (13, OUTPUT);
Serial.begin(115200);
delay(100);
configureReceiver();
previousTime= micros();
meanTime = 1500;
digitalWrite(13,HIGH);
}
const long windUp = 1000;
void loop() {
int numc;
short temp1, temp2;
float error;
float dTerm;
float timeFactor;
float invTimeFactor;
float tmp;
rcCommand1 = commandFilter(rcCommand1,pin1.Width);
rcCommand2 = commandFilter(rcCommand2,pin2.Width);
rcCommand3 = commandFilter(rcCommand3,pin3.Width);
rcCommand4 = commandFilter(rcCommand4,pin4.Width);
Serial.print(rcCommand1);
Serial.print(",");
Serial.print(rcCommand2);
Serial.print(",");
Serial.print(rcCommand3);
Serial.print(",");
Serial.print(rcCommand4);
Serial.println();
currentTime = micros();
deltaTime = currentTime - previousTime;
previousTime = currentTime;
meanTime = (39*meanTime + deltaTime)/40;
timeFactor = deltaTime/meanTime;
invTimeFactor = meanTime/deltaTime;
//++++++ motor control ++++++++++++++++++++++++++++++++++
temp1 = rcCommand1;
constrain(temp1,0,255);
analogWrite(MOTOR_1,temp1);
temp1 = rcCommand2;
constrain(temp1,0,255);
analogWrite(MOTOR_2,temp1);
temp1 = rcCommand3;
constrain(temp1,0,255);
analogWrite(MOTOR_3,temp1);
temp1 = rcCommand4;
constrain(temp1,0,255);
analogWrite(MOTOR_4,temp1);
delay(100);
}
자작 조종기를 살리다.
PCB 에 남아있는 실크를 보니 2009 라고 써있는 것 보니 무려 5년전에 만든 것이네.
창고의 박스에서 꺼내 먼지를 털어내니 여기 저기 망가지고 볼품없다.
게다가 어떻게 구동되는지 기억조차 가물가물..했는데
마침 코드가 블로그에 남아있어 복기하는데 큰 도움을 줬다.
취미를 모두 접는 바람에 최초 실험을 할때에 준비할게 많아 영 귀찮았지만,
꾹 참고 해서 결국 성공.
"귀찮음을 이겨내야 훌륭한 어른이 될 수 있다"