diff --git a/docs/images/ssd1306.jpeg b/docs/images/ssd1306.jpeg new file mode 100644 index 00000000..e24fda4d Binary files /dev/null and b/docs/images/ssd1306.jpeg differ diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 672be7d2..6c6ecd83 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable (nrf24l01-receiver-example nrf24l01-receiver.cxx) add_executable (nrf24l01-broadcast-example nrf24l01-broadcast.cxx) add_executable (es08a-example es08a.cxx) add_executable (hcsr04-example hcsr04.cxx) +add_executable (ssd1306-oled-example ssd1306-oled.cxx) add_executable (ssd1308-oled-example ssd1308-oled.cxx) add_executable (ssd1327-oled-example ssd1327-oled.cxx) add_executable (max44000-example max44000.cxx) @@ -270,6 +271,7 @@ target_link_libraries (nrf24l01-receiver-example nrf24l01 ${CMAKE_THREAD_LIBS_IN target_link_libraries (nrf24l01-broadcast-example nrf24l01 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (es08a-example servo ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (hcsr04-example hcsr04 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (ssd1306-oled-example i2clcd ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ssd1308-oled-example i2clcd ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ssd1327-oled-example i2clcd ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (max44000-example max44000 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/ssd1306-oled.cxx b/examples/c++/ssd1306-oled.cxx new file mode 100644 index 00000000..07421e31 --- /dev/null +++ b/examples/c++/ssd1306-oled.cxx @@ -0,0 +1,149 @@ +/* + * Author Marc Graham + * Copyright (c) 2015 Intel Corporation. + * + * Adapted from ssd1308 library. + * Author: Yevgeniy Kiveish + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "ssd1306.h" + +#define DEVICE_ADDRESS 0x3C +#define BUS_NUMBER 0x6 + +static uint8_t intel_logo[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 192, 192, 192, 224, + 224, 224, 224, 240, 240, 248, 248, 120, 120, 120, 120, 60, 60, 60, 60, 60, + 62, 30, 30, 30, 30, 30, 30, 30, 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 31, 31, 31, 31, 31, + 30, 62, 62, 62, 62, 126, 126, 124, 124, 252, 252, 248, 248, 240, 240, 240, + 224, 224, 224, 192, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, + 128, 0, 56, 56, 28, 30, 14, 15, 15, 7, 7, 7, 7, 3, 3, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 192, 193, 195, 195, + 195, 7, 15, 15, 63, 127, 255, 255, 255, 254, 252, 252, 240, 192, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 192, 192, 240, 248, 124, 124, 60, 0, 0, 0, 0, 159, 159, + 159, 159, 159, 159, 159, 159, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, + 0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, 128, 128, 128, 128, + 128, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 192, 192, 192, 192, 192, 192, 128, + 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 0, 0, 0, 3, 7, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 255, 255, 255, 255, 255, + 255, 255, 0, 0, 224, 248, 252, 252, 255, 127, 15, 15, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 255, 255, 255, 255, 15, 15, 15, 15, 15, 15, 255, 255, 255, 255, 255, + 255, 255, 252, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 15, 15, + 15, 15, 15, 224, 224, 252, 254, 255, 255, 255, 255, 159, 159, 143, 143, + 135, 135, 143, 159, 255, 255, 255, 255, 255, 255, 252, 248, 0, 0, 0, 255, + 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, + 224, 248, 248, 255, 255, 255, 255, 255, 127, 15, 255, 255, 255, 255, 255, + 255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, + 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, + 255, 255, 255, 255, 255, 192, 192, 192, 192, 192, 31, 31, 255, 255, 255, + 255, 255, 255, 231, 231, 199, 199, 199, 199, 199, 199, 199, 199, 231, 231, + 231, 231, 199, 135, 0, 0, 0, 63, 255, 255, 255, 255, 255, 255, 255, 0, 0, + 0, 0, 224, 240, 248, 248, 252, 254, 255, 255, 255, 127, 63, 63, 31, 15, 7, + 7, 1, 0, 0, 63, 63, 255, 255, 255, 255, 255, 240, 192, 192, 128, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 3, 3, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, + 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 3, 3, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 0, 0, 0, 1, 3, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 7, 7, 7, + 7, 7, 3, 3, 3, 1, 0, 0, 0, 0, 1, 3, 3, 7, 135, 135, 135, 192, 192, 0, 0, 7, + 7, 3, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 15, + 31, 127, 127, 127, 255, 255, 252, 252, 252, 248, 240, 240, 240, 224, 224, + 224, 192, 192, 192, 192, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 192, 192, 192, 192, 192, + 224, 224, 224, 224, 240, 240, 240, 240, 248, 248, 248, 248, 252, 252, 252, + 254, 254, 255, 255, 255, 255, 255, 255, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 3, 3, 3, 7, 7, 7, 15, 15, 31, 31, 31, 63, 63, 63, 63, 63, 127, 127, 127, + 127, 127, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 255, 255, 255, 255, 255, 255, 255, 127, 127, 127, 127, 127, 127, 127, 127, + 63, 63, 63, 63, 63, 31, 31, 31, 31, 31, 15, 15, 15, 15, 7, 7, 7, 7, 3, 3, + 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }; + +int +main(int argc, char **argv) +{ +//! [Interesting] + upm::SSD1306 *lcd = new upm::SSD1306(BUS_NUMBER, DEVICE_ADDRESS); + + lcd->clear(); + lcd->stopscroll(); + lcd->draw(intel_logo, 1024); + + sleep(3); + + lcd->clear(); + lcd->setCursor(2, 0); + lcd->write("Hello"); + lcd->setCursor(3,0); + lcd->write("World"); + + sleep(3); + + lcd->invert(true); + + sleep(3); + + lcd->dim(true); + + sleep(3); + + lcd->dim(false); + + sleep(3); + + lcd->invert(false); + lcd->startscrollright(0x00, 0x0F); + + sleep(5); + + lcd->stopscroll(); + lcd->startscrollleft(0x00, 0x0F); + + sleep(5); + + lcd->stopscroll(); + lcd->startscrolldiagleft(0x00,0x0F); + + sleep(5); + + lcd->stopscroll(); + lcd->startscrolldiagright(0x00,0x0F); + + sleep(5); + + lcd->stopscroll(); + + delete lcd; +//! [Interesting] + return 0; +} diff --git a/examples/javascript/oled_ssd1306.js b/examples/javascript/oled_ssd1306.js new file mode 100644 index 00000000..b3ceac7f --- /dev/null +++ b/examples/javascript/oled_ssd1306.js @@ -0,0 +1,151 @@ +/* + * Author: Marc Graham + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + +var intel_logo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 192, 192, 192, 224, +224, 224, 224, 240, 240, 248, 248, 120, 120, 120, 120, 60, 60, 60, 60, 60, +62, 30, 30, 30, 30, 30, 30, 30, 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 31, 31, 31, 31, 31, +30, 62, 62, 62, 62, 126, 126, 124, 124, 252, 252, 248, 248, 240, 240, 240, +224, 224, 224, 192, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, +128, 0, 56, 56, 28, 30, 14, 15, 15, 7, 7, 7, 7, 3, 3, 1, 1, 1, 1, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 192, 193, 195, 195, +195, 7, 15, 15, 63, 127, 255, 255, 255, 254, 252, 252, 240, 192, 0, 0, 0, +0, 0, 0, 0, 0, 128, 192, 192, 240, 248, 124, 124, 60, 0, 0, 0, 0, 159, 159, +159, 159, 159, 159, 159, 159, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, +128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, +0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, 128, 128, 128, 128, +128, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 192, 192, 192, 192, 192, 192, 128, +128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 3, 7, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 255, 255, 255, 255, 255, +255, 255, 0, 0, 224, 248, 252, 252, 255, 127, 15, 15, 3, 1, 0, 0, 0, 0, 0, +0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, +255, 255, 255, 255, 255, 15, 15, 15, 15, 15, 15, 255, 255, 255, 255, 255, +255, 255, 252, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 15, 15, +15, 15, 15, 224, 224, 252, 254, 255, 255, 255, 255, 159, 159, 143, 143, +135, 135, 143, 159, 255, 255, 255, 255, 255, 255, 252, 248, 0, 0, 0, 255, +255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, +224, 248, 248, 255, 255, 255, 255, 255, 127, 15, 255, 255, 255, 255, 255, +255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, +255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, +0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, +255, 255, 255, 255, 255, 192, 192, 192, 192, 192, 31, 31, 255, 255, 255, +255, 255, 255, 231, 231, 199, 199, 199, 199, 199, 199, 199, 199, 231, 231, +231, 231, 199, 135, 0, 0, 0, 63, 255, 255, 255, 255, 255, 255, 255, 0, 0, +0, 0, 224, 240, 248, 248, 252, 254, 255, 255, 255, 127, 63, 63, 31, 15, 7, +7, 1, 0, 0, 63, 63, 255, 255, 255, 255, 255, 240, 192, 192, 128, 0, 0, 0, +0, 0, 0, 0, 0, 1, 3, 3, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, +0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 3, 3, 7, 7, 7, +7, 7, 7, 7, 7, 7, 0, 0, 0, 1, 3, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 7, 7, 7, +7, 7, 3, 3, 3, 1, 0, 0, 0, 0, 1, 3, 3, 7, 135, 135, 135, 192, 192, 0, 0, 7, +7, 3, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 15, +31, 127, 127, 127, 255, 255, 252, 252, 252, 248, 240, 240, 240, 224, 224, +224, 192, 192, 192, 192, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 192, 192, 192, 192, 192, +224, 224, 224, 224, 240, 240, 240, 240, 248, 248, 248, 248, 252, 252, 252, +254, 254, 255, 255, 255, 255, 255, 255, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +3, 3, 3, 7, 7, 7, 15, 15, 31, 31, 31, 63, 63, 63, 63, 63, 127, 127, 127, +127, 127, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, +254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, +255, 255, 255, 255, 255, 255, 255, 127, 127, 127, 127, 127, 127, 127, 127, +63, 63, 63, 63, 63, 31, 31, 31, 31, 31, 15, 15, 15, 15, 7, 7, 7, 7, 3, 3, +3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0]; + +function exit() +{ + lcd = null; + lcdObj.cleanUp(); + lcdObj = null; + process.exit(0); +} + +// Load i2clcd module +var lcdObj = require('jsupm_i2clcd'); +var lcd = new lcdObj.SSD1306(6, 0x3c); +var next = 0; + +lcd.clear(); +lcd.setCursor(2, 0); +lcd.write("Hello"); +lcd.setCursor(3, 0); +lcd.write("World!"); + +setInterval(function(){ + loop(); +}, +3000 ); + +function loop(){ + switch(next) + { + case 0: + lcd.invert(true) + break; + case 1: + lcd.dim(true); + break; + case 2: + lcd.invert(false); + break; + case 3: + lcd.startscrollright(0x00, 0x0F); + break; + case 4: + lcd.startscrollleft(0x00, 0x0F); + break; + case 5: + lcd.startscrolldiagleft(0x00, 0x0F) + break; + case 6: + lcd.startscrolldiagright(0x00, 0x0F) + break; + case 7: + var logo = new lcdObj.uint8Array(intel_logo.length); + for(var x = 0 ; x < intel_logo.length ; x++){ + logo.setitem(x, intel_logo[x]); + } + lcd.stopscroll(); + lcd.clear(); + lcd.draw(logo, 1024); + break; + case 8: + default: + lcd.stopscroll(); + lcd.clear(); + lcd.setCursor(2, 0); + lcd.write("All"); + lcd.setCursor(3, 0); + lcd.write("Done!"); + exit(); + } + next++; +} diff --git a/src/lcd/CMakeLists.txt b/src/lcd/CMakeLists.txt old mode 100644 new mode 100755 index e2ee87e0..c21ea8a9 --- a/src/lcd/CMakeLists.txt +++ b/src/lcd/CMakeLists.txt @@ -1,6 +1,6 @@ set (libname "i2clcd") set (classname "lcd") set (libdescription "upm lcd/oled displays") -set (module_src lcd.cxx lcm1602.cxx jhd1313m1.cxx ssd1308.cxx eboled.cxx ssd1327.cxx sainsmartks.cxx) -set (module_h lcd.h lcm1602.h jhd1313m1.h ssd1308.h eboled.h ssd1327.h ssd.h sainsmartks.h) +set (module_src lcd.cxx lcm1602.cxx jhd1313m1.cxx ssd1308.cxx eboled.cxx ssd1327.cxx sainsmartks.cxx ssd1306.cxx) +set (module_h lcd.h lcm1602.h jhd1313m1.h ssd1308.h eboled.h ssd1327.h ssd.h sainsmartks.h ssd1306.h) upm_module_init() diff --git a/src/lcd/javaupm_i2clcd.i b/src/lcd/javaupm_i2clcd.i index 9ff85405..2daa0c98 100644 --- a/src/lcd/javaupm_i2clcd.i +++ b/src/lcd/javaupm_i2clcd.i @@ -27,6 +27,7 @@ #include "ssd.h" #include "ssd1327.h" #include "ssd1308.h" + #include "ssd1306.h" #include "eboled.h" #include "lcm1602.h" #include "jhd1313m1.h" @@ -37,6 +38,7 @@ %include "ssd.h" %include "ssd1327.h" %include "ssd1308.h" +%include "ssd1306.h" %include "eboled.h" %include "lcm1602.h" %include "jhd1313m1.h" diff --git a/src/lcd/jsupm_i2clcd.i b/src/lcd/jsupm_i2clcd.i old mode 100644 new mode 100755 index 68cc4578..9b53d23b --- a/src/lcd/jsupm_i2clcd.i +++ b/src/lcd/jsupm_i2clcd.i @@ -43,3 +43,8 @@ %{ #include "sainsmartks.h" %} + +%include "ssd1306.h" +%{ + #include "ssd1306.h" +%} diff --git a/src/lcd/pyupm_i2clcd.i b/src/lcd/pyupm_i2clcd.i old mode 100644 new mode 100755 index 76ce65e1..1bcb1ab7 --- a/src/lcd/pyupm_i2clcd.i +++ b/src/lcd/pyupm_i2clcd.i @@ -46,3 +46,8 @@ %{ #include "sainsmartks.h" %} + +%include "ssd1306.h" +%{ + #include "ssd1306.h" +%} diff --git a/src/lcd/ssd1306.cxx b/src/lcd/ssd1306.cxx new file mode 100644 index 00000000..90d67d39 --- /dev/null +++ b/src/lcd/ssd1306.cxx @@ -0,0 +1,320 @@ +/* + * Author: Marc Graham + * Copyright (c) 2015 Intel Corporation + * + * Adapted from ssd1308 library. + * Author: Yevgeniy Kiveisha + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "hd44780_bits.h" +#include "ssd1306.h" + +using namespace upm; + +SSD1306::SSD1306(int bus_in, int addr_in) : m_i2c_lcd_control(bus_in) +{ + int vccstate = SSD1306_SWITCHCAPVCC; + _vccstate = vccstate; + + int LCD_CMD = 0x00; + + m_lcd_control_address = addr_in; + m_name = "SSD1306"; + + mraa_result_t error = m_i2c_lcd_control.address(m_lcd_control_address); + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + + if (error != mraa_SUCCESS) { + fprintf(stderr, "Failed to initialize i2c bus\n"); + return; + } + + m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_OFF); // display off + usleep(4500); + //ADD 1306 stuff + // Init sequence for 128x64 OLED module // 0xAE + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 + m_i2c_lcd_control.writeReg(LCD_CMD, 0x80); // the suggested ratio 0x80 + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETMULTIPLEX); // 0xA8 + m_i2c_lcd_control.writeReg(LCD_CMD, 0x3F); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETDISPLAYOFFSET); // 0xD3 + m_i2c_lcd_control.writeReg(LCD_CMD, 0x0); // no offset + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETSTARTLINE | 0x0); // line #0 + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_CHARGEPUMP); // 0x8D + if (vccstate == SSD1306_EXTERNALVCC) { + m_i2c_lcd_control.writeReg(LCD_CMD, 0x10); + } else { + m_i2c_lcd_control.writeReg(LCD_CMD,0x14); + } + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_MEMORYMODE); // 0x20 + m_i2c_lcd_control.writeReg(LCD_CMD, 0x00); // 0x0 act like ks0108 + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SEGREMAP | 0x1); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_COMSCANDEC); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETCOMPINS); // 0xDA + m_i2c_lcd_control.writeReg(LCD_CMD, 0x12); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETCONTRAST); // 0x81 + if (vccstate == SSD1306_EXTERNALVCC) { + m_i2c_lcd_control.writeReg(LCD_CMD, 0x9F); + } else { + m_i2c_lcd_control.writeReg(LCD_CMD, 0xCF); + } + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETPRECHARGE); // 0xd9 + if (vccstate == SSD1306_EXTERNALVCC) { + m_i2c_lcd_control.writeReg(LCD_CMD, 0x22); + } else { + m_i2c_lcd_control.writeReg(LCD_CMD,0xF1); + } + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SETVCOMDETECT); // 0xDB + m_i2c_lcd_control.writeReg(LCD_CMD, 0x40); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_DISPLAYALLON_RESUME); // 0xA4 + m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_SET_NORMAL_1306); // 0xA6 + + //END 1306 Stuff + m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_ON); // display on + usleep(4500); + setNormalDisplay(); // set to normal display '1' is ON + + clear(); + setAddressingMode(PAGE); +} + +SSD1306::~SSD1306() +{ +} + +mraa_result_t +SSD1306::draw(uint8_t* data, int bytes) +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t error = mraa_SUCCESS; + + setAddressingMode(HORIZONTAL); + for (int idx = 0; idx < bytes; idx++) { + m_i2c_lcd_control.writeReg(LCD_DATA, data[idx]); + } + + return error; +} + +/* + * ************** + * virtual area + * ************** + */ +mraa_result_t +SSD1306::write(std::string msg) +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t error = mraa_SUCCESS; + + setAddressingMode(PAGE); + for (std::string::size_type i = 0; i < msg.size(); ++i) { + writeChar(msg[i]); + } + + return error; +} + +mraa_result_t +SSD1306::setCursor(int row, int column) +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t error = mraa_SUCCESS; + + error = m_i2c_lcd_control.writeReg(LCD_CMD, BASE_PAGE_START_ADDR + row); // set page address + error = m_i2c_lcd_control.writeReg(LCD_CMD, + BASE_LOW_COLUMN_ADDR + (8 * column & 0x0F)); // set column + // lower address + error = m_i2c_lcd_control.writeReg(LCD_CMD, + BASE_HIGH_COLUMN_ADDR + + ((8 * column >> 4) & 0x0F)); // set column higher address + + return error; +} + +mraa_result_t +SSD1306::clear() +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t error = mraa_SUCCESS; + uint8_t columnIdx, rowIdx; + + m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_OFF); // display off + for (rowIdx = 0; rowIdx < 8; rowIdx++) { + setCursor(rowIdx, 0); + + // clear all columns + for (columnIdx = 0; columnIdx < 16; columnIdx++) { + writeChar(' '); + } + } + m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_ON); // display on + home(); + + return error; +} + +mraa_result_t +SSD1306::home() +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + return setCursor(0, 0); +} + +/* + * ************** + * private area + * ************** + */ +mraa_result_t +SSD1306::writeChar(uint8_t value) +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t rv; + if (value < 0x20 || value > 0x7F) { + value = 0x20; // space + } + + for (uint8_t idx = 0; idx < 8; idx++) { + rv = m_i2c_lcd_control.writeReg(LCD_DATA, BasicFont[value - 32][idx]); + } + + return rv; +} + +mraa_result_t +SSD1306::setNormalDisplay() +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + return m_i2c_lcd_control.writeReg(LCD_CMD, + DISPLAY_CMD_SET_NORMAL_1306); // set to normal display '1' is + // ON +} + +mraa_result_t +SSD1306::setAddressingMode(displayAddressingMode mode) +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t rv; + rv =m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_MEM_ADDR_MODE); // set addressing mode + rv =m_i2c_lcd_control.writeReg(LCD_CMD, mode); // set page addressing mode + return rv; +} + + +mraa_result_t +SSD1306::invert(bool i) +{ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + mraa_result_t rv; + if(i){ + rv = m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_SET_INVERT_1306); + } else { + rv = m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_SET_NORMAL_1306); + } + return rv; +} + + +void SSD1306::startscrollright(uint8_t start, uint8_t stop){ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_RIGHT_HORIZONTAL_SCROLL); + m_i2c_lcd_control.writeReg(LCD_CMD,0X00); + m_i2c_lcd_control.writeReg(LCD_CMD,start); + m_i2c_lcd_control.writeReg(LCD_CMD,0X00); + m_i2c_lcd_control.writeReg(LCD_CMD,stop); + m_i2c_lcd_control.writeReg(LCD_CMD,0X00); + m_i2c_lcd_control.writeReg(LCD_CMD,0XFF); + m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_ACTIVATE_SCROLL); +} + + +void SSD1306::startscrollleft(uint8_t start, uint8_t stop){ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_LEFT_HORIZONTAL_SCROLL); + m_i2c_lcd_control.writeReg(LCD_CMD,0X00); + m_i2c_lcd_control.writeReg(LCD_CMD,start); + m_i2c_lcd_control.writeReg(LCD_CMD,0X00); + m_i2c_lcd_control.writeReg(LCD_CMD,stop); + m_i2c_lcd_control.writeReg(LCD_CMD,0X00); + m_i2c_lcd_control.writeReg(LCD_CMD,0XFF); + m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_ACTIVATE_SCROLL); +} + +void SSD1306::startscrolldiagright(uint8_t start, uint8_t stop){ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SET_VERTICAL_SCROLL_AREA); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X00); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_LCDHEIGHT); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X00); + m_i2c_lcd_control.writeReg(LCD_CMD, start); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X00); + m_i2c_lcd_control.writeReg(LCD_CMD, stop); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X01); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_ACTIVATE_SCROLL); +} + +void SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop){ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_SET_VERTICAL_SCROLL_AREA); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X00); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_LCDHEIGHT); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X00); + m_i2c_lcd_control.writeReg(LCD_CMD, start); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X00); + m_i2c_lcd_control.writeReg(LCD_CMD, stop); + m_i2c_lcd_control.writeReg(LCD_CMD, 0X01); + m_i2c_lcd_control.writeReg(LCD_CMD, SSD1306_ACTIVATE_SCROLL); +} + +void SSD1306::stopscroll(void){ + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_DEACTIVATE_SCROLL); +} + +// Dim the display +// dim = true: display is dimmed +// dim = false: display is normal +void SSD1306::dim(bool dim) { + m_i2c_lcd_control.frequency(MRAA_I2C_FAST); + uint8_t contrast; + + if (dim) { + contrast = 0; // Dimmed display + } else { + if (_vccstate == SSD1306_EXTERNALVCC) { + contrast = 0x9F; + } else { + contrast = 0xCF; + } + } + // the range of contrast to too small to be really useful + // it is useful to dim the display + m_i2c_lcd_control.writeReg(LCD_CMD,SSD1306_SETCONTRAST); + m_i2c_lcd_control.writeReg(LCD_CMD,contrast); +} diff --git a/src/lcd/ssd1306.h b/src/lcd/ssd1306.h new file mode 100644 index 00000000..429d4c82 --- /dev/null +++ b/src/lcd/ssd1306.h @@ -0,0 +1,230 @@ +/* + * Author: Marc Graham + * Copyright (c) 2015 Intel Corporation + * + * Adapted from ssd1308 library. + * Author: Yevgeniy Kiveisha + * Copyright (c) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include +#include +#include "lcd.h" +#include "ssd.h" + +namespace upm +{ +const uint8_t DISPLAY_CMD_SET_NORMAL_1306 = 0xA6; +const uint8_t SSD1306_SETCONTRAST = 0x81; +const uint8_t SSD1306_DISPLAYALLON_RESUME =0xA4; +const uint8_t SSD1306_DISPLAYALLON = 0xA5; +const uint8_t DISPLAY_CMD_SET_INVERT_1306 = 0xA7; + +const uint8_t SSD1306_SETDISPLAYOFFSET =0xD3; +const uint8_t SSD1306_SETCOMPINS = 0xDA; + +const uint8_t SSD1306_SETVCOMDETECT = 0xDB; + +const uint8_t SSD1306_SETDISPLAYCLOCKDIV = 0xD5; +const uint8_t SSD1306_SETPRECHARGE = 0xD9; + +const uint8_t SSD1306_SETMULTIPLEX = 0xA8; + +const uint8_t SSD1306_SETLOWCOLUM = 0x00; +const uint8_t SSD1306_SETHIGHCOLUMN = 0x10; + +const uint8_t SSD1306_SETSTARTLINE = 0x40; + +const uint8_t SSD1306_MEMORYMODE = 0x20; +const uint8_t SSD1306_COLUMNADDR = 0x21; +const uint8_t SSD1306_PAGEADDR = 0x22; + +const uint8_t SSD1306_COMSCANINC = 0xC0; +const uint8_t SSD1306_COMSCANDEC = 0xC8; + +const uint8_t SSD1306_SEGREMAP = 0xA0; + +const uint8_t SSD1306_CHARGEPUMP = 0x8D; + +const uint8_t SSD1306_EXTERNALVCC = 0x1; +const uint8_t SSD1306_SWITCHCAPVCC = 0x2; + +// Scrolling const uint8_t s +const uint8_t SSD1306_ACTIVATE_SCROLL = 0x2F; +const uint8_t SSD1306_DEACTIVATE_SCROLL = 0x2E; +const uint8_t SSD1306_SET_VERTICAL_SCROLL_AREA = 0xA3; +const uint8_t SSD1306_RIGHT_HORIZONTAL_SCROLL = 0x26; +const uint8_t SSD1306_LEFT_HORIZONTAL_SCROLL = 0x27; +const uint8_t SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29; +const uint8_t SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A; + +const uint8_t SSD1306_BLACK = 0; +const uint8_t SSD1306_WHITE = 1; +const uint8_t SSD1306_LCDWIDTH = 128; +const uint8_t SSD1306_LCDHEIGHT = 64; + +/** + * @library i2clcd + * @sensor ssd1306 + * @comname SSD1306 OLED Display + * @altname Adafruit SSD1306 OLED Display 0.96" + * @type display + * @man adafruit + * @web https://www.adafruit.com/datasheets/SSD1306.pdf + * @web http://www.farnell.com/datasheets/609753.pdf + * @con i2c + * + * @brief API for SSD1306 I2C-controlled OLED displays + * + * SSD1306 is a 128x64 dot-matrix OLED/PLED segment driver with a + * controller. This device is available from many suppliers for a + * very low cost. This implementation was tested using a generic + * SSD1306 device from eBay. + * + * @image html ssd1306.jpeg + * @snippet ssd1306-oled.cxx Interesting + */ +class SSD1306 : public LCD +{ + public: + /** + * SSD1306 constructor; calls libmraa initialisation functions + * + * @param bus I2C bus to use + * @param address Slave address the LCD is registered on + */ + SSD1306(int bus, int address = 0x3C); + /** + * SSD1306 destructor + */ + ~SSD1306(); + /** + * Draws an image; see examples/python/make_oled_pic.py for an + * explanation of how pixels are mapped to bytes + * + * @param data Buffer to read + * @param bytes Number of bytes to read from the pointer + * @return Result of the operation + */ + mraa_result_t draw(uint8_t* data, int bytes); + /** + * Writes a string to the LCD + * + * @param msg std::string to write to the display; note: only ASCII + * characters are supported + * @return Result of the operation + */ + mraa_result_t write(std::string msg); + /** + * Sets the cursor to specified coordinates + * + * @param row Row to set the cursor to + * @param column Column to set the cursor to + * @return Result of the operation + */ + mraa_result_t setCursor(int row, int column); + /** + * Clears the display of all characters + * + * @return Result of the operation + */ + mraa_result_t clear(); + /** + * Returns to the original coordinates (0,0) + * + * @return Result of the operation + */ + mraa_result_t home(); + /** + * Inverts the display + * + * @param i true to invert, false for normal display + * @return Result of the operation + */ + mraa_result_t invert(bool i); + /** + * Activate a scroll to the right for rows start through stop + * The display is 16 rows tall. To scroll the whole display, run: + * display.scrollright(0x00, 0x0F) + * + * @param start First row to scroll + * @param stop Last row to scroll + * @return void + */ + void startscrollright(uint8_t start, uint8_t stop); + /** + * Activate a scroll to the left for rows start through stop + * The display is 16 rows tall. To scroll the whole display, run: + * display.startscrollright(0x00, 0x0F) + * + * @param start First row to scroll + * @param stop Last row to scroll + * @return void + */ + void startscrollleft(uint8_t start, uint8_t stop); + /** + * Activate a scroll to the upper right for rows start through stop + * The display is 16 rows tall. To scroll the whole display, run: + * display.startscrollleft(0x00, 0x0F) + * + * @param start First row to scroll + * @param stop Last row to scroll + * @return void + */ + void startscrolldiagright(uint8_t start, uint8_t stop); + /** + * Activate a scroll to the upper left for rows start through stop + * The display is 16 rows tall. To scroll the whole display, run: + * display.startscrolldiaagright(0x00, 0x0F) + * + * @param start First row to scroll + * @param stop Last row to scroll + * @return void + */ + void startscrolldiagleft(uint8_t start, uint8_t stop); + /** + * Stops display scrolling. + * + * @return void + */ + void stopscroll(void); + /** + * Dims display + * + * @param dim True to dim display, false for max intensity + * @return Result of last operation + */ + void dim(bool dim); + + private: + mraa_result_t writeChar(uint8_t value); + mraa_result_t setNormalDisplay(); + mraa_result_t setAddressingMode(displayAddressingMode mode); + + int m_lcd_control_address; + mraa::I2c m_i2c_lcd_control; + + int _vccstate; +}; +}