C++ Library for the PsiSwarm Robot - Version 0.8
Dependents: PsiSwarm_V8_Blank_CPP Autonomia_RndmWlk
Fork of PsiSwarmV7_CPP by
Diff: display.cpp
- Revision:
- 0:d6269d17c8cf
- Child:
- 2:c6986ee3c7c5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/display.cpp Thu Feb 04 21:48:54 2016 +0000 @@ -0,0 +1,336 @@ +/* University of York Robotics Laboratory PsiSwarm Library: Display Driver Source File + * + * File: display.cpp + * + * (C) Dept. Electronics & Computer Science, University of York + * + * James Hilder, Alan Millard, Alexander Horsfield, Homero Elizondo, Jon Timmis + * + * PsiSwarm Library Version: 0.4 + * + * February 2016 + * + * Driver for the Midas 16x2 I2C LCD Display (MCCOG21605x6W) LCD + * [Farnell part 2218942 or 2063206] + * + */ + +#include "psiswarm.h" + +Timeout init_timeout; +Timeout backlight_timeout; +Timeout debug_timeout; +int backlight_on_time; +int backlight_off_time; +char backlight_step; +char multipage[200]; +char multipage_length = 0; +char preserve_line_1 [17]; +char preserve_line_2 [17]; +char c_row=0; +char c_column=0; +char p_row; +char p_column; + + +Display::Display(PinName sda, PinName scl, PinName reset, PinName backlight) : Stream("display"), _i2c(sda,scl), _reset(reset), _backlight(backlight) { +} + +Display::Display() : Stream("display"), _i2c(p28,p27), _reset(p29), _backlight(p30) { +} + +int Display::i2c_message(char byte){ + char bytes [2]; + bytes[0]=0x80; + bytes[1]=byte; + int ret=_i2c.write(LCD_ADDRESS,bytes,2); + wait(0.01); + return ret; +} + +int Display::disp_putc(int c){ + char message [2]; + message[0]=0x40; + message[1]=c; + _i2c.write(LCD_ADDRESS,message,2); + wait(0.01); + return c; +} + +void Display::init_display(char mode){ + //Set initial states: display on, cursor off + display_on = 1; + set_backlight_brightness(1); + cursor_on = 0; + blink_on = 0; + + _reset=1; + wait(0.02); + //Set reset low + _reset=0; + wait(0.001); + _reset=1; + wait(0.03); + i2c_message(0x38); + i2c_message(0x39); + i2c_message(0x14); + i2c_message(0x74); + i2c_message(0x54); + i2c_message(0x6F); + _set_display(); + clear_display(); + char psis[17]; + for(int i=0;i<16;i++){ + psis[i]=0x1D; + } + set_position(0,0); + write_string(psis,16); + set_position(1,0); + write_string(psis,16); + wait(0.25); + clear_display(); + if(mode == 0){ + set_position(0,0); + write_string(" YORK ROBOTICS"); + set_position(1,0); + write_string(" LABORATORY"); + init_timeout.attach(this,&Display::post_init,0.3);} + else { + set_position(0,0); + write_string("Hold button to"); + set_position(1,0); + write_string("launch demo code"); + } +} + +void Display::post_init(){ + clear_display(); + home(); + write_string("PSI SWARM ROBOT"); + set_position(1,0); + char line [17]; + sprintf(line,"VERSION %1.2f", SOFTWARE_VERSION_CODE ); + set_position(1,0); + write_string(line); + init_timeout.attach(this,&Display::post_post_init,0.3); +} + +void Display::post_post_init(){ + clear_display(); + home(); +} + +void Display::write_string(char * message){ + size_t length = strlen(message); + if (length > 16) length = 16; + char to_send [length+1]; + to_send[0]=0x40; + for(int i=0;i<length;i++){ + to_send[i+1] = message[i]; + } + _i2c.write(LCD_ADDRESS,to_send,length+1); + // Add to saved buffer + int count = 0; + for(int i=c_column;i<16;i++){ + if(count < length){ + if(c_row == 0) preserve_line_1[i] = message[count]; + else preserve_line_2[i] = message[count]; + } + count++; + } + c_column+=length; + if(c_column>15) c_column=15; +} + + +void Display::write_string(char * message, char length){ + char to_send [length+1]; + to_send[0]=0x40; + for(int i=0;i<length;i++){ + to_send[i+1] = message[i]; + } + _i2c.write(LCD_ADDRESS,to_send,length+1); + // Add to saved buffer + int count = 0; + for(int i=c_column;i<16;i++){ + if(count < length){ + if(c_row == 0) preserve_line_1[i] = message[count]; + else preserve_line_2[i] = message[count]; + } + count++; + } + c_column+=length; + if(c_column>15) c_column=15; +} + +void Display::set_position(char row, char column){ + if(row < 2 && column < 16){ + char pos = 128 +((row * 64)+column); + i2c_message(pos); + c_row= row; + c_column = column; + } +} + +void Display::set_cursor(char enable){ + cursor_on=enable; + _set_display(); +} + +void Display::set_blink(char enable){ + blink_on=enable; + _set_display(); +} + +void Display::set_display(char enable){ + display_on=enable; + _set_display(); +} + +void Display::set_backlight_brightness(float brightness){ + if(brightness > 1) brightness = 0; + if(brightness < 0) brightness = 0; + backlight_brightness = brightness; + if(backlight_brightness == 1) { + backlight_timeout.detach(); + _backlight = 1; + }else{ + if(backlight_brightness == 0){ + backlight_timeout.detach(); + _backlight = 0; + } else { + backlight_on_time = (int) (10000.0f * backlight_brightness); + backlight_off_time = 10000 - backlight_on_time; + backlight_step = 0; + _backlight = 0; + backlight_timeout.attach_us(this,&Display::IF_backlight_toggle,backlight_off_time); + } + } +} + +void Display::IF_backlight_toggle(){ + if(backlight_step == 0){ + _backlight = 1; + backlight_step = 1; + backlight_timeout.attach_us(this,&Display::IF_backlight_toggle,backlight_on_time); + } else { + _backlight = 0; + backlight_step = 0; + backlight_timeout.attach_us(this,&Display::IF_backlight_toggle,backlight_off_time); + } +} +void Display::clear_display(){ + for(int i=0;i<16;i++){ + preserve_line_1[i] = 0x20; + preserve_line_2[i] = 0x20; + } + i2c_message(0x01); +} + +void Display::home(){ + c_row = 0; + c_column = 0; + i2c_message(0x02); +} + +void Display::debug_page(char * message, char length){ + p_row=c_row; + p_column=c_column; + i2c_message(0x01); + home(); + char multipage_mode = 0; + char line_1[18]; + char line_2[18]; + line_1[0]=0x40; + line_2[0]=0x40; + if(length > 16){ + strncpy(line_1+1, message, 16); + char f_length = length - 16; + if(f_length > 16) { + f_length = 16; + multipage_mode = 1; + } + strncpy(line_2+1, message+16, f_length); + line_1[17]=0; + line_2[f_length+1]=0; + _i2c.write(LCD_ADDRESS,line_1,17); + set_position(1,0); + _i2c.write(LCD_ADDRESS,line_2,f_length+1); + } else { + strncpy(line_1+1, message, length); + _i2c.write(LCD_ADDRESS,line_1,length+1); + } + if(multipage_mode == 1){ + strncpy(multipage, message + 32, length - 32); + multipage_length = length - 32; + debug_timeout.attach(this,&Display::IF_debug_multipage,PAGE_TIME); + } else debug_timeout.attach(this,&Display::IF_restore_page,CLEAR_TIME); +} + +void Display::IF_restore_page(){ + i2c_message(0x01); + home(); + char line_1[17]; + char line_2[17]; + line_1[0]=0x40; + line_2[0]=0x40; + strncpy(line_1+1, preserve_line_1, 16); + strncpy(line_2+1, preserve_line_2, 16); + _i2c.write(LCD_ADDRESS,line_1,17); + set_position(1,0); + _i2c.write(LCD_ADDRESS,line_2,17); + set_position(p_row,p_column); +} + +void Display::IF_debug_multipage(){ + i2c_message(0x01); + home(); + char multipage_mode = 0; + char line_1[18]; + char line_2[18]; + line_1[0]=0x40; + line_2[0]=0x40; + if(multipage_length > 16){ + strncpy(line_1+1, multipage, 16); + char f_length = multipage_length - 16; + if(f_length > 16) { + f_length = 16; + multipage_mode = 1; + } + strncpy(line_2+1, multipage+16, f_length); + line_1[17]=0; + line_2[f_length+1]=0; + _i2c.write(LCD_ADDRESS,line_1,17); + set_position(1,0); + _i2c.write(LCD_ADDRESS,line_2,f_length+1); + } else { + strncpy(line_1+1, multipage, multipage_length); + _i2c.write(LCD_ADDRESS,line_1,multipage_length+1); + } + if(multipage_mode == 1){ + char temp[200]; + strncpy(temp, multipage + 32, multipage_length - 32); + multipage_length -= 32; + strncpy(multipage, temp, multipage_length); + debug_timeout.attach(this,&Display::IF_debug_multipage,PAGE_TIME); + }else debug_timeout.attach(this,&Display::IF_restore_page,CLEAR_TIME); +} + +void Display::_set_display(){ + char mode = 8; + if(display_on>0) mode += 4; + if(cursor_on>0) mode += 2; + if(blink_on>0) mode ++; + i2c_message(mode); +} + + +int Display::_putc (int c) { + putc(c); + return(c); +} + +int Display::_getc (void) { + char r = 0; + return(r); +}