Assembly

1. Attach metal couplers and wheels on the motors.

2. Assembly the motors with metal brackets.

3. Assembly the chassis with delivered screws.

4. Attach CORE2 board on the chassis.

5. Attach phone holder on the chassis.

6. Add power supply.

Connect motors with metal brackets and wheels.

Attach motors on the chassis.

Use M3 screws and nuts to attach CORE2.

Use holes on the chassis.

Originally we used wooden plate, metal bracket and some screws to make a phone holder.

But we have also prepared a beautiful 3D printable phone holder.

Tighten it with some countersunk screws and add soft material.

As you can see (on the right) it is tighten in the gap, so you can easily adapt it to any phone.

Attach power supply with some zip ties.

Circuit diagram

In our configuration the only thing you have to do in electronics is to connect 4 motors delivered with the chassis, attach ESP8266 adapter delivered with CORE2 and add power supply, for example Li-Po battery.

hMotA - front-right motor

hMotB - front-left motor

hMotC - back-right motor

hMotD - back-left motor


Code:

The source code is available here on github and also included here (main only):

#include "hFramework.h" 
#include "hCloudClient.h" 
#define GEAR1   200 
#define GEAR2   600 
#define GEAR3   1000 
int speed; 
bool keyW = false; 
bool keyS = false; 
bool keyA = false; 
bool keyD = false; 
hGPIO& lightLeft = hSens1.pin1; 
hGPIO& lightRight = hSens2.pin1; 
void debugConsole_task() 
{ 
	char ch; 
	platform.printf("Wpisz znak:\r\n"); 
	for (;;) { 
		if (platform.read(&ch, 1) == 1) { 
			platform.printf("echo: %c\r\n", ch); 
		} 
	} 
} 
void status_task() 
{ 
	while (1) { 
		platform.ui.label("lb_bat").setText("%2f V", sys.getSupplyVoltage()); 
		platform.ui.progressBar("pb_bat").setValue(sys.getSupplyVoltageMV() / 15); //supply voltage milivolts 
		platform.ui.label("l1").setText("hMot1 enc = %d", hMot1.getEncoderCnt()); 
		sys.delay(1000); 
	} 
} 
void cfgHandler() 
{ 
	auto l1 = platform.ui.label("l1"); 
	auto g1 = platform.ui.button("g1"); 
	auto g2 = platform.ui.button("g2"); 
	auto g3 = platform.ui.button("g3"); 
	platform.ui.loadHtml({Resource::WEBIDE, "/web_ui/ui.html"}); 
	platform.ui.video.enable(); 
} 
void onKeyEvent(KeyEventType type, KeyCode code) 
{ 
	platform.ui.console("cl1").printf("\r\nKE: t:%d, c:%d [%dms]", type, code, sys.getRefTime()); 
	switch (code) { 
	case KeyCode::Up:    keyW = type == KeyEventType::Pressed; break; 
	case KeyCode::Left:  keyA = type == KeyEventType::Pressed; break; 
	case KeyCode::Right: keyD = type == KeyEventType::Pressed; break; 
	case KeyCode::Down:  keyS = type == KeyEventType::Pressed; break; 
	case KeyCode::Key_T: 
		if (type == KeyEventType::Pressed) { 
			platform.ui.console("cl1").printf(" pressed"); 
			hServoModule.servo2.setWidth(1300); // 1.3 ms width 
		} else { 
			platform.ui.console("cl1").printf(" released"); 
			hServoModule.servo2.setWidth(2300); // 2.3 ms width 
		} 
		break; 
	default : break; 
	} 
} 
void onButtonEvent(hId id, ButtonEventType type) 
{ 
	platform.ui.console("cl1").printf("\r\nBE: t:%d, i:%s [%dms]", type, id.str(), sys.getRefTime()); 
	if (id == "g1") { 
		if (type == ButtonEventType::Pressed) { 
			speed = GEAR1; 
			platform.ui.label("l1").setText("Gear: 1"); 
		} 
		return; 
	} 
	if (id == "g2") { 
		if (type == ButtonEventType::Pressed) { 
			speed = GEAR2; 
			platform.ui.label("l1").setText("Gear: 2"); 
		} 
		return; 
	} 
	if (id == "g3") { 
		if (type == ButtonEventType::Pressed) { 
			speed = GEAR3; 
			platform.ui.label("l1").setText("Gear: 3"); 
		} 
		return; 
	} 
	keyW = 0; 
	keyS = 0; 
	keyA = 0; 
	keyD = 0; 
	if (id == "move_up") { 
		if (type == ButtonEventType::Pressed) { 
			keyW = 1; 
		} 
	} 
	if (id == "move_down") { 
		if (type == ButtonEventType::Pressed) { 
			keyS = 1; 
		} 
	} 
	if (id == "move_left") { 
		if (type == ButtonEventType::Pressed) { 
			keyA = 1; 
		} 
	} 
	if (id == "move_right") { 
		if (type == ButtonEventType::Pressed) { 
			keyD = 1; 
		} 
	} 
} 
void hMain() 
{ 
	speed = GEAR2;...
Read more »