C++ Library for the PsiSwarm Robot - Version 0.8

Dependents:   PsiSwarm_V8_Blank_CPP Autonomia_RndmWlk

Fork of PsiSwarmV7_CPP by Psi Swarm Robot

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