[Raspberry Pi +. net mf: Smart car for video monitoring] Remote Control

Source: Internet
Author: User

Raspberry Pi is an open-source hardware that has recently become popular. Its devices only have credit card sizes. It runs a Linux system and is designed for students in programming education. I have been studying Microsoft's technology for more than a decade. I tried to learn linux in the middle, but I had to give up on the steep learning curve. In recent years, in-depth research on embedded systems naturally won't go around linux. Fortunately, with Raspberry Pi, first, it is easy to cultivate interest in learning; second, it is a global technical exchange that facilitates problem locating and solving; so in the course of learning, the secrets of linux have been slowly uncovered, giving you the opportunity to explore the beauty of the linux design architecture.

In the past, I used the. NET MicroFramework system to control smart vehicles, but its functions were relatively simple. The addition of Raspberry Pi and the addition of Sony PS2 remote control, video monitoring and manipulator became very interesting. Is connected by the device:


From the point of view, the function is relatively complex and requires 9 PWM, 7 of which are from the lingxiao evaluation board (. NETMicro Framework Development Board) three control manipulator, the remaining four PWM and eight GPIO drive four motors respectively; the other two PWM from Raspberry Pi, used to drive the camera cloud platform (two degrees of freedom, can rotate horizontally and vertically); Raspberry Pi leads to a GPIO to control the LED flashing, the camera selects a matching camera; Because Sony PS2 receiver is connected to the lingxiao evaluation board, therefore, some key information needs to be sent to Raspberry Pi through the serial port, and the Raspberry Pi drives the camera cloud platform.

Is the assembled device image:


To give you an intuitive impression, first watch a Demo Video:

Http://v.youku.com/v_show/id_XNjY2MTE1NjQ0.html

 

As we need to introduce a lot of content, we will explain how to create a video surveillance Smart Car in four articles: Remote Control: mainly describes how to receive and process signals from Sony PS2 remote control; control (. net mf): Mainly used for explanation. net mf how to drive the car and control manipulator; Control Article (Raspberry Pi): mainly describes how to use Raspberry Pi to drive GPIO, PWM and serial communication; video article: this section describes how to set up the video service, how to watch videos remotely, and how to configure the self-starting program.

This article first introduces how to obtain the Sony PS2 remote control signal.

A remote control description


The Sony PS2 game host has two joystick and 14 function keys (excluding the mode key). It is very suitable for us to control complicated systems, such as the control manipulator, camera cloud platform, car travel and speed.

At present, the online purchase of such a game handle is about 40 yuan, the price is very high.

Device B Wiring

A receiving header is included when you buy a game handle. Some stores also provide two types of connectors, one is the SPI interface and the other is the serial port. The SPI interface is actually performing a level conversion (3V3 => 5 V) without any special processing. A single AVR chip is added in the middle of the serial port Adapter. You can actively send the collected key information through the serial port (TTL level. It is relatively simple to use, but there are functional problems. First, the program seems to have a bug. When operating the PSB_PINK and PSB_BLUE buttons, the return value is different from other keys (PSB_PINK only raises the sending key value, PSB_BLUE presses and raises the sending key value, and other keys press the issuing key value ). In addition, when the key value of the joystick is L2 or R2, the X/Y value of the corresponding joystick is sent. If multiple keys are simultaneously pressed, they cannot be differentiated.

Therefore, we use the SPI interface (in fact, we can also directly connect the handle receiving head to our lingxiao system, but add the adapter Board to facilitate wiring ).

The lingxiao evaluation board includes a USB, a tf card slot, and a RS485 interface, and 31 pins (two standard. NETGadgeteer interfaces and a sub-board interface ). Provides 2 SPI, 1 I2C, 5 serial ports, 16 PWM, 12 AD, 2 DA, and several GPIO (the Pin can be reused ).

The four motors and two drives require 4 GPIO and 2-way PWM respectively. To facilitate the connection, we use them separately. NET Gadgeteer interface is provided, so the remote controller receiver is connected to the sub-board interface.

The wiring is as follows:

Mainboard. SubPort. Pin2 (5 V) -- power supply (4.vcc. if directly connected, connect to Pin1 3V3)

Mainboard. SubPort. Pin12 (PA5) -- att (6. ATT selected)

Mainboard. SubPort. Pin10 (PA7) -- cmd (2. Command)

Mainboard. SubPort. Pin8 (PC7) -- dat (1. Documents)

Mainboard. SubPort. Pin14 (PB3) -- clk (7. Clock)

Mainboard. SubPort. Pin3 (GND) -- ground (GND)

[Note] the four gpios in the middle can be arbitrary, as long as they are specified in the program.

C user-driven development

Although the interface is similar to SPI, but the SPI interface is used for communication, set various modes (A/B/C/D ), communication is not normal (Series values such as 0xFF are returned ). Therefore, we adopt user-driven development with C ++.

I have written several articles about user-driven development. For more information, see. NETMicro Framework MDK C ++ secondary development.

We can directly modify and transplant the Arduino driver, including two files: ps2x_lib.h and ps2x_lib.cpp.

We need to modify the components related to GPIO operations and clock operations.

In the config_gamepad function, we add the GPIO initialization code.

MF-> CPU_GPIO_EnableOutputPin (att, FALSE );

MF-> CPU_GPIO_EnableOutputPin (cmd, FALSE );

MF-> CPU_GPIO_EnableInputPin (dat, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLUP );

MF-> CPU_GPIO_EnableOutputPin (clk, FALSE );

 

Original GPIO operation code:

Inline void PS2X: pai_set (void ){

* _ Blank _lport_set | = _ blank _mask;

}

Inline void PS2X: CMD_CLR (void ){

* _ Blank _lport_clr | = _ blank _mask;

}

Inline void PS2X: ATT_SET (void ){

* _ Att_lport_set | = _ att_mask;

}

Inline voidPS2X: ATT_CLR (void ){

* _ Att_lport_clr | = _ att_mask;

}

Inline boolPS2X: DAT_CHK (void ){

Return (* _ dat_lport & _ dat_mask )? True: false;

}

To:

// On pic32, usethe set/clr registers to make them atomic...

Inline void PS2X: CLK_SET (void ){

MF-> CPU_GPIO_SetPinState (SPI_CLK_Pin, TRUE );

}

Inline void PS2X: CLK_CLR (void ){

MF-> CPU_GPIO_SetPinState (SPI_CLK_Pin, FALSE );

}

Inline void PS2X: pai_set (void ){

MF-> CPU_GPIO_SetPinState (SPI_MO_Pin, TRUE );

}

Inline void PS2X: CMD_CLR (void ){

MF-> CPU_GPIO_SetPinState (SPI_MO_Pin, FALSE );

}

Inline void PS2X: ATT_SET (void ){

MF-> CPU_GPIO_SetPinState (SPI_CS_Pin, TRUE );

}

Inline voidPS2X: ATT_CLR (void ){

MF-> CPU_GPIO_SetPinState (SPI_CS_Pin, FALSE );

}

Inline boolPS2X: DAT_CHK (void ){

ReturnMF-> CPU_GPIO_GetPinState (SPI_MI_Pin );

}

 

Define several macros:

# DefinedelayMicroseconds MF-> HAL_Time_Sleep_MicroSeconds_InterruptEnabled

# Define millis () (MF-> HAL_Time_CurrentTime ()/1000)

# Define delay (x) MF-> HAL_Time_Sleep_MicroSeconds_InterruptEnabled (1000 * x)

 

Since there is no map function, we need to implement it ourselves:

Int map (INT32 x, int in_min, int in_max, int out_min, int out_max)

{

Return (x-in_min) * (out_max-out_min)/(in_max-in_min) + out_min;

}

In addition, some variable types are redefined, which will not be detailed here.

 

The following describes the programming of user-driven interfaces:

We pass a 32-bit integer number through the GeneralStream_Open2_UserDriver interface and pass in four GPIO values.

Int GeneralStream_Open2_UserDriver (int config)

{

// The first execution is required.

InitUserDriver ();

// Obtain the pointer of the system function

MF = (IGeneralStream_Function *) config;

// Configure IO

Att = (UINT8) (MF-> iParam1> 24 & 0xFF );

Cmd = (UINT8) (MF-> iParam1> 16 & 0xFF );

Dat = (UINT8) (MF-> iParam1> 8 & 0xFF );

Clk = (UINT8) (MF-> iParam1> 0 & 0xFF );

......

}

Here we use a function that is unique to the underlying. NET MicroFramework PAL: HAL_COMPLETION. You can regularly execute a function, similar to a multi-threaded mechanism (multiple can be defined ).

We define a scanning function for 20 ms to scan key values:

HcHander = MF-> HAL_COMPLETION_Initialize (ScanKey, NULL );

MF-> HAL_COMPLETION_EnqueueDelta (hcHander, 20000); // once every 20 ms

The complete scan Function Code is as follows:

VoidScanKey (void * arg)

{

If (error = 1 | type = 2)

{

InitPS2 ();

MF-> HAL_COMPLETION_EnqueueDelta (hcHander, 1000000); // 1 s execution

If (error = 1 | type = 2) return;

}

 

// Read status

Ps2x. read_gamepad (false, vibrate );

UINT8 button = 0;

For (int I = 0; I <16; I ++)

{

If (ps2x. NewButtonState (Buttons [I])

{

Button = ps2x. Button (Buttons [I]);

// MF-> debug_printf ("% s: % d \ r \ n", ButtonNames [I], button );

// MF-> LCD _printf ("% s: % d \ r \ n", ButtonNames [I], button );

If (button) ButtonState | = 1 <I;

Else ButtonState & = ~ (1 <I );

// Trigger the event

MF-> Notice_GenerateEvent (UserDriver_Hander, (byte) I <16 | button );

}

}

UINT8 lx = ps2x. Analog (PSS_LX );

UINT8 ly = ps2x. Analog (PSS_LY );

UINT8 rx = ps2x. Analog (PSS_RX );

UINT8 ry = ps2x. Analog (PSS_RY );

ButtonAnalog = lx <24 | ly <16 | rx <8 | ry;

If (frist! = 1)

{

If (lx! = Olx | ly! = Oly)

{

// MF-> LCD _printf ("lx: % d ly: % d \ r \ n", lx, ly );

// Trigger the event

MF-> Notice_GenerateEvent (UserDriver_Hander, (byte) 16 <16 | lx <8 | ly );

}

If (rx! = Orx | ry! = Ory)

{

// MF-> LCD _printf ("rx: % d ry: % d \ r \ n", rx, ry );

// Trigger the event

MF-> Notice_GenerateEvent (UserDriver_Hander, (byte) 17 <16 | rx <8 | ry );

}

}

Olx = lx; oly = ly; orx = rx; ory = ry; frist = 0;

MF-> HAL_COMPLETION_EnqueueDelta (hcHander, 20000); // once every 20 ms

}

In order to get both the key value and the joystick value, we also encapsulate an interface, the Code is as follows:

Int GeneralStream_IOControl2_UserDriver (int code, int parameter)

{

// Obtain the current button status

If (code = 0) return ButtonState;

Else if (code = 1) return ButtonAnalog;

Return-1;

}

The above code is compiled into a binfile, which can be directly deployed to the device through YFAccessFlash.

 

Next we will introduce the user C # code

Let's first make a simple encapsulation:

Public PS2 (Cpu. Pin clk, Cpu. Pin cmd, Cpu. Pin att, Cpu. Pin dat)

{

Gs = newGeneralStream ();

If (gs. open ("UserDriver", (int) clk <24 | (int) cmd <16 | (int) att <8 | (int) dat )) <= 0)

{

Throw new Exception ("OpenUserDriver failed! ");

}

Gs. Notice + = new GeneralStreamEventHandler (gs_Notice );

}

 

Void gs_Notice (uinthander, uint data, DateTimetimestamp)

{

// Debug. Print (hander. ToString () + "-" + data. ToString ());

If (hander = 1)

{

Keykey = (Key) (data> 16 & 0xFF );

Intstate = 0, x = 0, y = 0;

If (key = Key. LRocker | key = Key. RRocker)

{

X = (int) (data> 8 & 0xFF );

Y = (int) (data & 0xFF );

}

Else

{

State = (int) (data & 0xFF );

}

If (Click! = Null) Click (this, new ButtonArgs (key, state, x, y ));

}

}

 

Public class Program

{

Public static void Main ()

{

PS2ps2 = new PS2 (Mainboard. SubPort. Pin12, Mainboard. SubPort. Pin10, Mainboard. SubPort. Pin8, Mainboard. SubPort. Pin14

);

Ps2.Click + = newPS2.ClickHandle (ps2_Click );

Thread. Sleep (Timeout. Infinite );

}

 

Static void ps2_Click (objectsender, PS2.ButtonArgse)

{

Debug. Print (e. ToString ());

}

}

 

D. Test user application functions

Connect the device, run the above program, and operate the console handle. We can see the key information.

Article Navigation:

1. Remote Control of Raspberry Pi +. net mf Smart car for Video Monitoring

2. [Raspberry Pi +. net mf to create a video surveillance Smart Car] control (. net mf)

3. Control of Raspberry Pi +. net mf Smart car for video monitoring (Raspberry Pi)

4. Video of Raspberry Pi +. net mf Smart car for Video Monitoring

Summary:

1. With the user-driven C/C ++ secondary development interface, it is easy to transplant the relevant C/C ++ code.

2. The encapsulation performance of. NET Micro Framework allows your programs to focus only on the business logic, which is very simple and easy to use.

3. VS2010/VS2012 can debug. NET Micro Framework online (with breakpoints, single-step execution, etc.) to facilitate problem diagnosis and debugging.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.