Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: 3pi_Example_2 3pi_Lab1_Task2_Example1 3pi_Lab2_Task1_Example1 3pi_Line_Follow ... more
Diff: m3pi.cpp
- Revision:
- 0:56320ef879a6
- Child:
- 1:5523d6d1feec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m3pi.cpp Tue Apr 04 08:08:16 2017 +0000 @@ -0,0 +1,364 @@ +#include "m3pi.h" + +////////////////////////// constructor/destructor ////////////////////////////// + + +m3pi::m3pi() +{ + _serial = new Serial(p9,p10); + _reset = new DigitalOut(p23); + _button = new DigitalIn(p21); + _leds = new BusOut(p20,p19,p18,p17,p16,p15,p14,p13); +} + +m3pi::~m3pi() +{ + delete _serial; + delete _reset; + delete _button; + delete _leds; +} + +/////////////////////////////// public methods ///////////////////////////////// + +void m3pi::write_leds(int val) +{ + // check within limits + val = val > 255 ? 255 : val; + val = val < 0 ? 0 : val; + + _leds->write(val); +} + +void m3pi::init() +{ + _serial->baud(115200); + reset(); // hard rest of 3pi + stop(); // stop motors + lcd_clear(); // clear LCD + write_leds(0); // turn off LEDs + _button->mode(PullUp); // turn pull-up on +} + +void m3pi::get_signature(char *signature) +{ + _serial->putc(0x81); + _serial->gets(signature,7); +} + +void m3pi::get_raw_values(unsigned int *values) +{ + _serial->putc(0x86); + + for (int i=0; i<5; i++) { + char lsb = _serial->getc(); + char msb = _serial->getc(); + unsigned int value = (msb<<8 | lsb); + values[i]=value; + } +} + +void m3pi::get_calibrated_values(unsigned int *values) +{ + _serial->putc(0x87); + + for (int i=0; i<5; i++) { + char lsb = _serial->getc(); + char msb = _serial->getc(); + unsigned int value = (msb<<8 | lsb); + values[i]=value; + } + +} + +float m3pi::get_trimpot_value() +{ + _serial->putc(0xB0); + char lsb = _serial->getc(); + char msb = _serial->getc(); + // trimpot value in the range 0 - 1023 + float value = ( msb<<8 | lsb ) / 1023.0; + return value; +} + + +float m3pi::get_battery_voltage() +{ + _serial->putc(0xB1); + char lsb = _serial->getc(); + char msb = _serial->getc(); + // Battery in mV so convert to volts + float voltage = ( msb<<8 | lsb ) / 1000.0; + return voltage; +} + +void m3pi::play_music(const char notes[],int length) +{ + length = length < 0 ? 0 : length; + length = length > 100 ? 100 : length; + + _serial->putc(0xB3); + _serial->putc(length); + + for (int i = 0 ; i < length ; i++) { + _serial->putc(notes[i]); + } +} + + +void m3pi::calibrate() +{ + reset_calibration(); + + lcd_goto_xy(0,0); + lcd_print("Place on",8); + lcd_goto_xy(0,1); + lcd_print(" line ",8); + + wait(1.0); + + lcd_clear(); + lcd_goto_xy(0,0); + lcd_print(" Press ",8); + lcd_goto_xy(0,1); + lcd_print("to begin",8); + + while( read_button() ) { + // loop while waiting for button to be press + } + + wait(1.0); + + lcd_clear(); + lcd_goto_xy(0,0); + lcd_print("Reading ",8); + lcd_goto_xy(0,1); + lcd_print("Sensors ",8); + + spin_right(0.1); + + char led_val = 0; + Timer timer; + timer.start(); + + while (timer.read() < 10.0) { + write_leds(led_val++); + + if (led_val > 255) { + led_val = 0; + } + + _serial->putc(0xB4); + wait_ms(5); + } + + timer.stop(); + + write_leds(255); + stop(); + + lcd_clear(); + lcd_goto_xy(0,0); + lcd_print("Place on",8); + lcd_goto_xy(0,1); + lcd_print(" line ",8); + + while( read_button() ) { + // loop while waiting for button to be press + } + + lcd_clear(); + write_leds(0); + wait(1.0); +} + +void m3pi::reset_calibration() +{ + _serial->putc(0xB5); + wait_ms(50); +} + +int m3pi::get_line_position() +{ + _serial->putc(0xB6); + + // order is different from claimed in User Guide? + char lsb = _serial->getc(); + char msb = _serial->getc(); + int position = (msb<<8 | lsb); + + return position - 2000; +} + +float m3pi::get_normalised_line_position() +{ + int position = get_line_position(); + return float(position)/2000.0; +} + +void m3pi::lcd_clear() +{ + _serial->putc(0xB7); +} + +void m3pi::lcd_print(char text[],int length) +{ + length = length < 0 ? 0 : length; + length = length > 8 ? 8 : length; + + _serial->putc(0xB8); + _serial->putc(length); + + for (int i = 0 ; i < length ; i++) { + _serial->putc(text[i]); + } +} + +void m3pi::lcd_goto_xy(int x, int y) +{ + _serial->putc(0xB9); + _serial->putc(x); + _serial->putc(y); + +} + +void m3pi::auto_calibrate() +{ + reset_calibration(); // clear previous calibration + + _serial->putc(0xBA); + write_leds(0xFF); // LEDs on + while(1) { + if (_serial->readable()) { + break; + } + } + write_leds(0); // LEDs off +} + +void m3pi::left_motor(float speed) +{ + // check within bounds + speed = speed > 1.0 ? 1.0 : speed; + speed = speed < -1.0 ? -1.0 : speed; + + if (speed > 0.0) { // forward + _serial->putc(0xC1); + char s = char(127.0*speed); + _serial->putc(s); + } else { // backward - speed is negative + _serial->putc(0xC2); + char s = char(-127.0*speed); + _serial->putc(s); + } + +} + +void m3pi::right_motor(float speed) +{ + // check within bounds + speed = speed > 1.0 ? 1.0 : speed; + speed = speed < -1.0 ? -1.0 : speed; + + if (speed > 0.0) { // forward + _serial->putc(0xC5); + char s = char(127.0*speed); + _serial->putc(s); + } else { // backward - speed is negative + _serial->putc(0xC6); + char s = char(-127.0*speed); + _serial->putc(s); + } + +} + +// speeds from -1.0 to 1.0 (0 is stop) +void m3pi::motors(float left_speed,float right_speed) +{ + left_motor(left_speed); + right_motor(right_speed); +} + + +void m3pi::stop() +{ + left_motor(0.0); + right_motor(0.0); +} + +// speed in range 0.0 to 1.0 +void m3pi::forward(float speed) +{ + speed = speed > 1.0 ? 1.0 : speed; + speed = speed < 0.0 ? 0.0 : speed; + + left_motor(speed); + right_motor(speed); +} + +// speed in range 0 to 1.0 +void m3pi::reverse(float speed) +{ + speed = speed > 1.0 ? 1.0 : speed; + speed = speed < 0.0 ? 0.0 : speed; + + left_motor(-speed); + right_motor(-speed); +} + +void m3pi::spin_right(float speed) +{ + + speed = speed > 1.0 ? 1.0 : speed; + speed = speed < 0.0 ? 0.0 : speed; + + left_motor(speed); + right_motor(-speed); +} + +void m3pi::spin_left(float speed) +{ + + speed = speed > 1.0 ? 1.0 : speed; + speed = speed < 0.0 ? 0.0 : speed; + + left_motor(-speed); + right_motor(speed); +} + +int m3pi::read_button() +{ + return _button->read(); +} + +void m3pi::display_battery_voltage(int x,int y) +{ + float voltage = get_battery_voltage(); + + char buffer[8]; + sprintf(buffer,"%3.1f V",voltage); + + lcd_goto_xy(x,y); + lcd_print(buffer,5); +} + +void m3pi::display_signature(int x,int y) +{ + _serial->putc(0x81); + char buffer[7]; // including NULL terminator + _serial->gets(buffer,7); + + lcd_goto_xy(x,y); + lcd_print(buffer,6); +} + +/////////////////////////////// private methods //////////////////////////////// + +void m3pi::reset() +{ + // pulse the reset line (active-high) + _reset->write(0); + wait_ms(100); + _reset->write(1); + wait_ms(100); +} \ No newline at end of file