UKESF Headstart Summer School / PsiSwarm-Headstart

Dependents:   UKESF_Lab

Fork of PsiSwarmLibrary by James Hilder

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers display.cpp Source File

display.cpp

00001 /* University of York Robotics Laboratory PsiSwarm Library: Display Driver Source File
00002  * 
00003  * File: display.cpp
00004  *
00005  * (C) Dept. Electronics & Computer Science, University of York
00006  * 
00007  * James Hilder, Alan Millard, Alexander Horsfield, Homero Elizondo, Jon Timmis
00008  *
00009  * PsiSwarm Library Version: 0.41
00010  *
00011  * March 2016
00012  *
00013  * Driver for the Midas 16x2 I2C LCD Display (MCCOG21605x6W) LCD
00014  * [Farnell part 2218942 or 2063206]
00015  *
00016  */ 
00017  
00018 #include "psiswarm.h"
00019 
00020 Timeout init_timeout;
00021 Timeout backlight_timeout;
00022 Timeout debug_timeout;
00023 int backlight_on_time;
00024 int backlight_off_time;
00025 char backlight_step;
00026 char multipage[200];
00027 char multipage_length = 0;
00028 char preserve_line_1 [17];
00029 char preserve_line_2 [17];
00030 char c_row=0;
00031 char c_column=0;
00032 char p_row;
00033 char p_column;
00034 
00035 
00036 Display::Display(PinName sda, PinName scl, PinName reset, PinName backlight) :  Stream("display"), _i2c(sda,scl), _reset(reset), _backlight(backlight)  {
00037 }
00038 
00039 Display::Display() :  Stream("display"), _i2c(p28,p27), _reset(p29), _backlight(p30)  {
00040 }
00041 
00042 int Display::i2c_message(char byte){
00043    char bytes [2];
00044    bytes[0]=0x80;
00045    bytes[1]=byte;
00046    int ret=_i2c.write(LCD_ADDRESS,bytes,2);  
00047    wait(0.01);
00048    return ret;
00049 }
00050 
00051 int Display::disp_putc(int c){
00052    char message [2];
00053    message[0]=0x40;
00054    message[1]=c;
00055    _i2c.write(LCD_ADDRESS,message,2);
00056    wait(0.01);
00057    return c;
00058 }
00059 
00060 void Display::init_display(char mode){
00061    //Set initial states: display on, cursor off
00062    display_on = 1;
00063    set_backlight_brightness(1);
00064    cursor_on = 0;
00065    blink_on  = 0;
00066     
00067    _reset=1;
00068    wait(0.02);
00069    //Set reset low
00070    _reset=0;
00071    wait(0.001);
00072    _reset=1;
00073    wait(0.03);
00074    i2c_message(0x38); 
00075    i2c_message(0x39); 
00076    i2c_message(0x14); 
00077    i2c_message(0x74); 
00078    i2c_message(0x54); 
00079    i2c_message(0x6F); 
00080    _set_display();
00081    clear_display(); 
00082    char psis[17];
00083    for(int i=0;i<16;i++){
00084        psis[i]=0x1D;
00085    }
00086    set_position(0,0);
00087    write_string(psis,16);
00088    set_position(1,0);
00089    write_string(psis,16);
00090    wait(0.25);
00091    clear_display();
00092    if(mode == 0){
00093    set_position(0,0);
00094    write_string("  YORK ROBOTICS");
00095    set_position(1,0);
00096    write_string("   LABORATORY");
00097    init_timeout.attach(this,&Display::post_init,0.3);}
00098    else {      
00099    set_position(0,0);
00100    write_string("Hold button to");
00101    set_position(1,0);
00102    write_string("launch demo code");
00103     }
00104 } 
00105 
00106 void Display::post_init(){
00107     clear_display();
00108     home();
00109     write_string("PSI SWARM ROBOT");
00110     set_position(1,0);
00111     char line [17];
00112     sprintf(line,"VERSION %1.2f", SOFTWARE_VERSION_CODE  );
00113     set_position(1,0);
00114     write_string(line);
00115     init_timeout.attach(this,&Display::post_post_init,0.3);
00116 }
00117 
00118 void Display::post_post_init(){
00119     clear_display();
00120     home();
00121 }
00122 
00123 void Display::write_string(char * message){
00124    size_t length = strlen(message);
00125    if (length > 16) length = 16;
00126    char to_send [length+1];
00127    to_send[0]=0x40;
00128    for(int i=0;i<length;i++){
00129      to_send[i+1] = message[i];
00130    }
00131    _i2c.write(LCD_ADDRESS,to_send,length+1);
00132    // Add to saved buffer
00133    int count = 0;
00134    for(int i=c_column;i<16;i++){
00135        if(count < length){
00136             if(c_row == 0) preserve_line_1[i] = message[count];
00137             else preserve_line_2[i] = message[count];  
00138        }
00139        count++;
00140    }
00141    c_column+=length;
00142    if(c_column>15) c_column=15;
00143 }
00144 
00145 
00146 void Display::write_string(char * message, char length){
00147    char to_send [length+1];
00148    to_send[0]=0x40;
00149    for(int i=0;i<length;i++){
00150      to_send[i+1] = message[i];
00151    }
00152    _i2c.write(LCD_ADDRESS,to_send,length+1);
00153    // Add to saved buffer
00154    int count = 0;
00155    for(int i=c_column;i<16;i++){
00156        if(count < length){
00157             if(c_row == 0) preserve_line_1[i] = message[count];
00158             else preserve_line_2[i] = message[count];  
00159        }
00160        count++;
00161    }
00162    c_column+=length;
00163    if(c_column>15) c_column=15;
00164 }
00165 
00166 void Display::set_position(char row, char column){
00167   if(row < 2 && column < 16){
00168     char pos = 128 +((row * 64)+column);
00169     i2c_message(pos);
00170     c_row= row;
00171     c_column = column;
00172   }
00173 }
00174 
00175 void Display::set_cursor(char enable){
00176   cursor_on=enable;
00177   _set_display();
00178 }
00179 
00180 void Display::set_blink(char enable){
00181   blink_on=enable;
00182     _set_display();
00183 }
00184 
00185 void Display::set_display(char enable){
00186   display_on=enable;
00187     _set_display();
00188 }
00189 
00190 void Display::set_backlight_brightness(float brightness){
00191     if(brightness > 1) brightness = 0;
00192     if(brightness < 0) brightness = 0;
00193     backlight_brightness = brightness;
00194     if(backlight_brightness == 1) {
00195         backlight_timeout.detach();   
00196         _backlight = 1;
00197     }else{
00198         if(backlight_brightness == 0){
00199             backlight_timeout.detach();
00200             _backlight = 0;   
00201         }   else {
00202             backlight_on_time = (int) (10000.0f * backlight_brightness);
00203             backlight_off_time = 10000 - backlight_on_time;
00204             backlight_step = 0;
00205             _backlight = 0;
00206             backlight_timeout.attach_us(this,&Display::IF_backlight_toggle,backlight_off_time);
00207         }
00208     }
00209 }
00210 
00211 void Display::IF_backlight_toggle(){
00212     if(backlight_step == 0){
00213         _backlight = 1;
00214         backlight_step = 1;
00215         backlight_timeout.attach_us(this,&Display::IF_backlight_toggle,backlight_on_time);
00216     }   else {
00217         _backlight = 0;
00218         backlight_step = 0;
00219         backlight_timeout.attach_us(this,&Display::IF_backlight_toggle,backlight_off_time);
00220     }
00221 }
00222 void Display::clear_display(){
00223   for(int i=0;i<16;i++){
00224       preserve_line_1[i] = 0x20;
00225       preserve_line_2[i] = 0x20;
00226   }
00227   i2c_message(0x01);
00228 }
00229 
00230 void Display::home(){
00231   c_row = 0;
00232   c_column = 0;
00233   i2c_message(0x02);
00234 }
00235 
00236 void Display::debug_page(char * message, char length){
00237     p_row=c_row;
00238     p_column=c_column;
00239     i2c_message(0x01);
00240     home();
00241     char multipage_mode = 0;
00242     char line_1[18];
00243     char line_2[18];
00244     line_1[0]=0x40;
00245     line_2[0]=0x40;
00246     if(length > 16){
00247         strncpy(line_1+1, message, 16);
00248         char f_length = length - 16;
00249         if(f_length > 16) {
00250             f_length = 16;
00251             multipage_mode = 1;
00252         }
00253         strncpy(line_2+1, message+16, f_length);
00254         line_1[17]=0;
00255         line_2[f_length+1]=0;
00256         _i2c.write(LCD_ADDRESS,line_1,17);
00257         set_position(1,0);
00258         _i2c.write(LCD_ADDRESS,line_2,f_length+1);
00259     } else {
00260         strncpy(line_1+1, message, length);
00261         _i2c.write(LCD_ADDRESS,line_1,length+1);
00262         }
00263     if(multipage_mode == 1){
00264         strncpy(multipage, message + 32, length - 32);
00265         multipage_length = length - 32;
00266         debug_timeout.attach(this,&Display::IF_debug_multipage,PAGE_TIME);
00267     } else debug_timeout.attach(this,&Display::IF_restore_page,CLEAR_TIME);
00268 }
00269 
00270 void Display::IF_restore_page(){
00271     i2c_message(0x01);
00272     home();
00273     char line_1[17];
00274     char line_2[17];
00275     line_1[0]=0x40;
00276     line_2[0]=0x40;
00277     strncpy(line_1+1, preserve_line_1, 16);
00278     strncpy(line_2+1, preserve_line_2, 16);
00279     _i2c.write(LCD_ADDRESS,line_1,17);
00280     set_position(1,0);
00281     _i2c.write(LCD_ADDRESS,line_2,17);
00282     set_position(p_row,p_column);
00283 }
00284 
00285 void Display::IF_debug_multipage(){
00286     i2c_message(0x01);
00287     home();
00288     char multipage_mode = 0;
00289     char line_1[18];
00290     char line_2[18];
00291     line_1[0]=0x40;
00292     line_2[0]=0x40;
00293     if(multipage_length > 16){
00294         strncpy(line_1+1, multipage, 16);
00295         char f_length = multipage_length - 16;
00296         if(f_length > 16) {
00297             f_length = 16;
00298             multipage_mode = 1;
00299         }
00300         strncpy(line_2+1, multipage+16, f_length);
00301         line_1[17]=0;
00302         line_2[f_length+1]=0;
00303        _i2c.write(LCD_ADDRESS,line_1,17);
00304         set_position(1,0);
00305         _i2c.write(LCD_ADDRESS,line_2,f_length+1);
00306     } else  {
00307         strncpy(line_1+1, multipage, multipage_length);
00308         _i2c.write(LCD_ADDRESS,line_1,multipage_length+1);
00309         }
00310     if(multipage_mode == 1){
00311         char temp[200];
00312         strncpy(temp, multipage + 32, multipage_length - 32);
00313         multipage_length -= 32;
00314         strncpy(multipage, temp, multipage_length);
00315         debug_timeout.attach(this,&Display::IF_debug_multipage,PAGE_TIME);
00316     }else debug_timeout.attach(this,&Display::IF_restore_page,CLEAR_TIME);
00317 }
00318 
00319 void Display::_set_display(){
00320     char mode = 8;
00321     if(display_on>0) mode += 4;
00322     if(cursor_on>0) mode += 2;
00323     if(blink_on>0) mode ++;
00324     i2c_message(mode);
00325 }
00326 
00327 
00328 int Display::_putc (int c) {
00329     putc(c);
00330     return(c);
00331 }
00332 
00333 int Display::_getc (void) {
00334     char r = 0;
00335     return(r);
00336 }