[전동 Skateboard 만들기]#3 Wi-Fi 모듈 연결 및 Control 어플 구현

Posted by 카이젠8501 카이젠8501
2015.11.03 09:58 IT 개발/DIY 프로젝트

[전동 Skateboard 만들기]#3 Wi-Fi 모듈 연결 및 Control 어플 구현

Hardware of Wi-Fi Receiver

Wi-Fi 수신기는 스마트폰에서 데이터를 수신하여 스케이트 보드의 속도를 조절하는 장치이며, 하드웨어 구성은 아래와 같다.

20151029_143029

아래 사진은 완성된 하드웨어 사진이다. 배터리나 다른 보드들과의 circuit short를 방지하기 위해 절연 테이트를 부착하여 조금 부족해 보이지만 동작에는 문제가 없다.

오른쪽에 3핀, 2핀이 나와 있는데, 위에 3핀은 PWM,3.3V VCC,GND 핀이고, 아래 2핀은 배터리에서 받아 올 5V VCC, GND 핀이다.

20151030_082315

Wi-Fi Receiver Firmware

Source Code

Wi-Fi Receiver firmware는 아래 그림과 같은 구조로 동작된다. 스마트폰에서 Speed Up 명령을 주면 Wi-Fi Receiver는 속도를 5% 올리고 Speed Down 명령을 주면 속도를 5% 내린다.

20151030_084225

예외 상황에서는 아래 그림과 같이 Motor를 정지 한다. 단 Motor가 정지 되어도 가속도 때문에 스케이트 보드는 계속 움직일 수는 있다.

20151030_085505

Wi-Fi 수신기에 대한 소스코드는 아래 경로에서 다운로드 할 수 있다.
https://developer.mbed.org/users/kaizen/code/Wifi_Electric_Skateboard/

#include "mbed.h"
#include "Servo.h"
#include "WizFi250Interface.h"

#define SECURE WizFi250::SEC_WPA2_MIXED
#define SSID "Kaizen_Skate"
#define PASS "qwertyuiop"

#define SERVER_PORT    5000
#define STOP_MOTOR     50


#if defined(TARGET_WIZwiki_W7500P)
    WizFi250Interface wizfi250(PC_2,PC_3,PC_13,PC_14,PC_12,NC,115200);
    Serial pc(USBTX, USBRX);
    Servo motor_speed(PC_8);      // it used to percentage value ( 0 ~ 1 )
    DigitalOut green_led(LED2);    
    DigitalOut red_led(LED1);
    DigitalOut blue_led(LED3);
#endif

#define START_MSG       "START"
#define END_MSG         "END\n"
#define CONTROL_UP      "UPXX"
#define CONTROL_DOWN    "DOWN"
#define CONTROL_CRUISER "CRUI"
#define CONTROL_STOP    "STOP"

#define STATUS_CMD_OK   "OKXX"
#define STATUS_CMD_FAIL "FAIL"

#define CONTROL_MSG_SIZE    19

// Control Pkt Format : START,CONTROL,SPEED_VALUE,END
//                      START,UPXX,500,END
// Status Pkt Format : START,CONTROL,SPEED_VALUE,STATUS,END

struct control_pkt{
    char start_msg[6];
    char control_msg[5];
    char speed_msg[4];
    char end_msg[4];
};
void parse(char buffer[], int *j, char *string);

int main() {    
    int recv_cnt,j;
    volatile float speed_value = 0.5;
    char recv_control_msg[100];
    char status_msg[100];
    control_pkt control;

    pc.baud(115200);
    green_led = 1; red_led = 1; blue_led = 1;

    wizfi250.init();
    wizfi250.setAntMode(WizFi250::PCB);
    wizfi250.setAddress("192.168.100.2","255.255.255.0","192.168.100.1");
    if ( wizfi250.connect(SECURE, SSID, PASS, WizFi250::WM_AP))
    {
        red_led = 0;
        return -1;
    }
    printf("IP Address is %s\r\n", wizfi250.getIPAddress());
    green_led = 0; red_led = 0; blue_led = 0;

    TCPSocketServer server;
    TCPSocketConnection client;

    while(true)
    {
        if( client.is_connected() == false )
        {
            green_led = 1; red_led = 1; blue_led = 0;            
            client.close();
            server.close();

            if(speed_value == 0.5)
            {
                server.bind(SERVER_PORT);
                server.listen();

                printf("\nWait for new connection...\r\n");
                server.accept(client);
                client.set_blocking(false, 1500);
            }
            else if(speed_value <= 0.4)
            {
                printf("Speed decrease +\r\n");

                speed_value = 0.5;
                motor_speed = speed_value;
            }
            else
            {
                printf("Speed decrease -\r\n");
                speed_value = 0.5;  motor_speed = speed_value;
            }
        }
        else
        {
            motor_speed = speed_value;

            green_led = 0; red_led = 1; blue_led = 1;
            //recv_cnt = client.receive_all((char*)recv_control_msg, sizeof(control)-1);
            recv_cnt = client.receive_all((char*)recv_control_msg, sizeof(control));

            j=0;
            parse(recv_control_msg, &j, control.start_msg);
            parse(recv_control_msg, &j, control.control_msg);
            parse(recv_control_msg, &j, control.speed_msg);
            parse(recv_control_msg, &j, control.end_msg);

            if(recv_cnt > 0)
            {
                if( (strncmp(control.start_msg,START_MSG,sizeof(control.start_msg)) != 0) || 
                    (strncmp(control.end_msg,END_MSG,sizeof(control.end_msg)) != 0) )
                {
                    printf("TEST Error\r\n");
                    sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_FAIL,END_MSG);
                    client.send_all((char*)status_msg,strlen(status_msg));
                    continue;
                }

                if( strncmp(control.control_msg,CONTROL_UP,sizeof(control.control_msg)) == 0 )
                {
                    speed_value += 0.05; 
                    motor_speed = speed_value;
                    printf("TEST UP %f\r\n",speed_value); 
                }
                else if( strncmp(control.control_msg,CONTROL_DOWN,sizeof(control.control_msg)) == 0)
                {
                    speed_value -= 0.05; 
                    motor_speed = speed_value;
                    printf("TEST DOWN %f\r\n",speed_value);
                }
                else if( strncmp(control.control_msg,CONTROL_CRUISER,sizeof(control.control_msg)) == 0)
                {
                    printf("TEST CRUISER\r\n"); 
                    speed_value = (float)(atoi(control.speed_msg)) / 100;
                    motor_speed = speed_value;
                }
                else if( strncmp(control.control_msg,CONTROL_STOP,sizeof(control.control_msg)) == 0)
                {
                    printf("TEST STOP\r\n"); 
                    speed_value = 0.5;
                    motor_speed = speed_value;
                }
                else
                {
                    printf("TEST Error 1-2\r\n");
                    sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_FAIL,END_MSG);
                    client.send_all((char*)status_msg,strlen(status_msg));
                    continue;
                }

                sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_OK,END_MSG);
                client.send_all((char*)status_msg,strlen(status_msg));
            }
            else
            {
                sprintf(status_msg,"%s,%03d,%s,%s\n",START_MSG,int(speed_value*100),STATUS_CMD_OK,END_MSG);
                client.send_all((char*)status_msg,strlen(status_msg));
            }
        }
    }// while
}

void parse(char buffer[], int *j, char *string) {
//extracts next location string data item from buffer
    int i=0;
    for (i=0; i<=strlen(buffer); i++) {  //TOTAL SIZE OF RETURNED DATA
        if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string
            //comma is the string field delimiter
            string[i]=0; //SETS END OF SRTRING TO 0
            *j=*j+i+1; //UPDATES to 1 after comma seperated value
            break;
        } else string[i]=buffer[*j+i]; //Keep adding to the string
    }
}

스마트폰 어플

Screenshot_2015-10-29-16-20-25

Source Code

https://github.com/kaizen8501/WiFi_Skateboard

Demo Video


저작자 표시
신고
이 댓글을 비밀 댓글로
    • ㅇㅇ
    • 2016.12.17 21:51 신고
    너무 어렵다.........
    • 안녕하세요^^

      어느 부분이 어려우신지 말씀해 주시면 제가 아는 한도 내에서 자세히 설명 해 드리도록 하겠습니다^^

전동 Skateboard 만들기 #2

Posted by 카이젠8501 카이젠8501
2015.11.03 09:57 IT 개발/DIY 프로젝트

전동 Skateboard 만들기 #2

Mortor Test

Hardware 구성

다들 아시겠지만, 서보모터는 MCU의 PWM 파형을 이용하여 구동한다. PWM 파형을 제어하기 위해 Cortex-M0 계열의 WIZwiki-W7500ECO 보드를 이용하였으며, 하드웨어 구성은 아래 그림과 같다.

20151029_143257

Test Software

Software는 mbed 환경에서 구현하였다. 서보 모터를 제어하기 위해, mbed에서는 Servo 라이브러리를 제공하며 사용방법은 아래 주소를 참고 하기 바란다. (Servo Library)

내 스케이트 보드에 장착되어 있는 보드의 모터에 어떤 값을 입력하였을 때, 전진하고 후진하는지 알아 보기 위해 아래와 같은 테스트 코드를 작성하였다. mbed Servo는 0 ~ 1 사이의 값으로 PWM 파형을 생성하며, 스케이트 보드에 장착된 모터는 0.4 ~ 0.55 값에서 중립 상태를 보인다.

#include "mbed.h"
#include "Servo.h"

int main() {    
    uint8_t ch;
    volatile float speed_value = 0.5;

    Servo myservo(PC_8);
    Serial pc(USBTX,USBRX);

    pc.baud(115200);
    wait(1);
    pc.printf("TEST Start\r\n");

    while(1)
    {
        pc.printf("speed : %f\r\n",speed_value);
        myservo = speed_value;

        ch = pc.getc();

        if(ch == 'u')
        {
            speed_value += 0.001;
        }
        else if(ch == 'd')
        {
            speed_value -= 0.001;
        }

        else if(ch == 's')
        {
            myservo = 0.5;
            wait(0.5);

            speed_value = 0.41;
            myservo = speed_value;
            wait(5);

            speed_value = 0.5;
            myservo = speed_value;

        }
    }
}

위 코드는 https://developer.mbed.org/users/kaizen/code/Servo_HelloWorld/에서 확인 및 다운로드 할 수 있다.


저작자 표시
신고
이 댓글을 비밀 댓글로