├── bme280-i2c ├── bme280-i2c.j-flash ├── MainClass.java ├── App.java └── BME280.java ├── iLCD ├── sdcard │ ├── sdcard.lcdp-flash │ ├── MainClass.java │ └── App.java └── i2c-scanner │ ├── i2c-scanner.lcdp-flash │ ├── MainClass.java │ └── App.java ├── javaino-lcd-keypad-shield ├── io.j-ports ├── settings.j-sett ├── docs │ └── lcd-keypad-shield-pinout.jpg ├── javaino-lcd-keypad-shield.j-flash ├── MainClass.java ├── LCDKeypadShield.java ├── App.java └── LiquidCrystal.java ├── lcd1602-pcf8574-i2c ├── lcd1602-i2c.j-flash ├── MainClass.java ├── App.java └── LcdPcf8574.java ├── .gitignore ├── README.md └── LICENSE /bme280-i2c/bme280-i2c.j-flash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/bme280-i2c/bme280-i2c.j-flash -------------------------------------------------------------------------------- /iLCD/sdcard/sdcard.lcdp-flash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/iLCD/sdcard/sdcard.lcdp-flash -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/io.j-ports: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/javaino-lcd-keypad-shield/io.j-ports -------------------------------------------------------------------------------- /iLCD/i2c-scanner/i2c-scanner.lcdp-flash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/iLCD/i2c-scanner/i2c-scanner.lcdp-flash -------------------------------------------------------------------------------- /lcd1602-pcf8574-i2c/lcd1602-i2c.j-flash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/lcd1602-pcf8574-i2c/lcd1602-i2c.j-flash -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/settings.j-sett: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/javaino-lcd-keypad-shield/settings.j-sett -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/docs/lcd-keypad-shield-pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/javaino-lcd-keypad-shield/docs/lcd-keypad-shield-pinout.jpg -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/javaino-lcd-keypad-shield.j-flash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/452/javaino-examples/master/javaino-lcd-keypad-shield/javaino-lcd-keypad-shield.j-flash -------------------------------------------------------------------------------- /bme280-i2c/MainClass.java: -------------------------------------------------------------------------------- 1 | import javax.*; 2 | import hw.*; 3 | 4 | public class MainClass { 5 | 6 | public static void main(String[] args) { 7 | try { 8 | App app = new App(); 9 | app.run(); 10 | } catch(MainThreadException ex) { 11 | Logger.e(ex.getMessage()); 12 | } catch(Exception ex) { 13 | Logger.e(ex.getMessage()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lcd1602-pcf8574-i2c/MainClass.java: -------------------------------------------------------------------------------- 1 | import javax.*; 2 | import hw.*; 3 | 4 | public class MainClass { 5 | 6 | public static void main(String[] args) { 7 | try { 8 | App app = new App(); 9 | app.run(); 10 | } catch(MainThreadException ex) { 11 | Logger.e(ex.getMessage()); 12 | } catch(Exception ex) { 13 | Logger.e(ex.getMessage()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/MainClass.java: -------------------------------------------------------------------------------- 1 | import javax.*; 2 | import hw.*; 3 | 4 | public class MainClass { 5 | 6 | public static void main(String[] args) { 7 | try { 8 | App app = new App(); 9 | app.run(); 10 | } catch(MainThreadException ex) { 11 | Logger.e(ex.getMessage()); 12 | } catch(Exception ex) { 13 | Logger.e(ex.getMessage()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /iLCD/sdcard/MainClass.java: -------------------------------------------------------------------------------- 1 | import ilcd.*; 2 | import javax.*; 3 | import hw.*; 4 | 5 | public class MainClass { 6 | 7 | public static void main(String[] args) { 8 | try { 9 | App app = new App(); 10 | app.run(); 11 | } catch(MainThreadException ex) { 12 | General.resetAll(); 13 | Logger.e(ex.getMessage()); 14 | } catch(Exception ex) { 15 | Logger.e(ex.getMessage()); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iLCD/i2c-scanner/MainClass.java: -------------------------------------------------------------------------------- 1 | import ilcd.*; 2 | import javax.*; 3 | import hw.*; 4 | 5 | public class MainClass { 6 | 7 | public static void main(String[] args) { 8 | try { 9 | App app = new App(); 10 | app.run(); 11 | } catch(MainThreadException ex) { 12 | General.resetAll(); 13 | Logger.e(ex.getMessage()); 14 | } catch(Exception ex) { 15 | Logger.e(ex.getMessage()); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Javaino (JoC) 2 | *.ini 3 | 4 | # Compiled class file 5 | *.class 6 | 7 | # Log file 8 | *.log 9 | 10 | # BlueJ files 11 | *.ctxt 12 | 13 | # Mobile Tools for Java (J2ME) 14 | .mtj.tmp/ 15 | 16 | # Package Files # 17 | *.jar 18 | *.war 19 | *.nar 20 | *.ear 21 | *.zip 22 | *.tar.gz 23 | *.rar 24 | 25 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 26 | hs_err_pid* 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Javaino](https://joc.systems/en/hardware/javaino.html) examples 2 | Javaino - Java on microcontroller, bare metal JVM 3 | 4 | ### Current embedded Java examples list 5 | 1. [LCD1602 with PCF8574 driver via i2c bus](lcd1602-pcf8574-i2c) 6 | 1. [LCD1602 via GPIO](javaino-lcd-keypad-shield) 7 | 1. [bme280](bme280-i2c) 8 | 1. [iLCD i2c Scanner](iLCD/i2c-scanner) 9 | 1. [iLCD sdcard](iLCD/sdcard) 10 | 11 | 12 | ### Development board: 13 | 1. [Javaino](https://joc.systems/en/hardware/javaino.html) 14 | 1. [JoC Module with size only 24x36 mm](https://joc.systems/en/joc-module.html) 15 | 1. [10.2 LCD panel with DPC3090 32-bit controller allow execute Java code](https://demmel.com/en/products/ilcd-panels/id-10-1024x600-px.html) 16 | 17 | Project file extensions: 18 | .lcdp-flash 19 | .j-flash -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/LCDKeypadShield.java: -------------------------------------------------------------------------------- 1 | import hw.IO; 2 | import hw.IOException; 3 | import LiquidCrystal; 4 | 5 | public class LCDKeypadShield { 6 | 7 | private Config config; 8 | private LiquidCrystal lcd; 9 | 10 | public LCDKeypadShield() throws IOException { 11 | lcd = new LiquidCrystal(); 12 | lcd.home(); 13 | lcd.clear(); 14 | } 15 | 16 | public LiquidCrystal getLCD() { 17 | return lcd; 18 | } 19 | 20 | public void update() throws IOException { 21 | if (config == null) 22 | return; 23 | 24 | int adcKeyIn = IO.getADCValue(IO.ANALOG_IN_0) >> 2; 25 | 26 | if (adcKeyIn > 1000) return; // We make this the 1st option for speed reasons since it will be the most likely result 27 | // For V1.1 us this threshold 28 | // need calibrate for your board 29 | if (adcKeyIn < 50) { 30 | config.rightKeyPressed(); 31 | return; 32 | } 33 | if (adcKeyIn < 250) { 34 | config.upKeyPressed(); 35 | return; 36 | }; 37 | if (adcKeyIn < 470) { 38 | config.downKeyPressed(); 39 | return; 40 | } 41 | if (adcKeyIn < 730) { 42 | config.leftKeyPressed(); 43 | return; 44 | } 45 | if (adcKeyIn < 850) { 46 | config.selectKeyPressed(); 47 | } 48 | } 49 | 50 | public void configure(Config config) { 51 | this.config = config; 52 | } 53 | } 54 | 55 | interface Config { 56 | void selectKeyPressed(); 57 | void leftKeyPressed(); 58 | void upKeyPressed(); 59 | void downKeyPressed(); 60 | void rightKeyPressed(); 61 | } 62 | -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/App.java: -------------------------------------------------------------------------------- 1 | import javax.*; 2 | import hw.*; 3 | import LiquidCrystal; 4 | import LCDKeypadShield; 5 | 6 | public class App extends Application { 7 | 8 | private LCDKeypadShield shield; 9 | private LiquidCrystal lcd; 10 | 11 | public App() throws IOException { 12 | //IO.setDate(20, 07, 12, 0); 13 | //IO.setTime(19, 10, 10); 14 | shield = new LCDKeypadShield(); 15 | lcd = shield.getLCD(); 16 | 17 | Config config = new Config() { 18 | 19 | public void selectKeyPressed() { 20 | showPressedButton("Select"); 21 | } 22 | 23 | public void leftKeyPressed() { 24 | showPressedButton("Left"); 25 | } 26 | 27 | public void upKeyPressed() { 28 | showPressedButton("Up"); 29 | } 30 | 31 | public void downKeyPressed() { 32 | showPressedButton("Down"); 33 | } 34 | 35 | public void rightKeyPressed() { 36 | showPressedButton("Right"); 37 | } 38 | }; 39 | shield.configure(config); 40 | } 41 | 42 | private void showPressedButton(String name) { 43 | lcd.setCursor(0, 1); 44 | lcd.print("Btn " + name); 45 | } 46 | 47 | public void onUpdate() { 48 | try { 49 | lcd.clear(); 50 | 51 | int millis = System.currentTimeMillis() / 60000; 52 | 53 | lcd.print("UP " + millis + "m"); 54 | 55 | lcd.print(" " + IO.getTime()); 56 | 57 | shield.update(); 58 | 59 | Thread.sleep(250); 60 | } catch (Exception ex) { 61 | Logger.e(ex.getMessage()); 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /iLCD/sdcard/App.java: -------------------------------------------------------------------------------- 1 | import ilcd. * ; 2 | import javax.events. * ; 3 | import javax. * ; 4 | import hw. * ; 5 | import comm. * ; 6 | import java.util. * ; 7 | import java.io.File; 8 | 9 | public class App extends Application implements OnTouchListener { 10 | 11 | public App() throws Exception { 12 | General.resetAll(); 13 | Touch.setTouchFieldReportingEnabled(true); 14 | EventManagement.getTouchEventDispatcher().addListener(this); 15 | Size displaySize = Control.getDisplaySize(); 16 | Touch.setTouchFieldWidth(displaySize.getWidth()); 17 | Touch.setTouchFieldHeight(displaySize.getHeight()); 18 | Touch.createDefineTouchField(1, 0); 19 | scan(); 20 | } 21 | 22 | public void onTouch(TouchEvent event) { 23 | if (event.isTouchPressed()) { 24 | scan(); 25 | } 26 | } 27 | 28 | private void scan() { 29 | clear(); 30 | println("SDCard"); 31 | File root = new File("/"); 32 | println("Mounted: " + root.isMounted()); 33 | println("Total Space: " + root.getTotalSpace()); 34 | println("Free Space: " + root.getFreeSpace()); 35 | walk("/"); 36 | } 37 | public void walk(String path) { 38 | try { 39 | File root = new File(path); 40 | File[] list = root.listFiles(); 41 | 42 | if (list == null) return; 43 | 44 | for (int i = 0; i < list.length; i++) { 45 | if (list[i].isDirectory()) { 46 | walk(list[i].getAbsolutePath()); 47 | println("Dir: " + list[i].getAbsolutePath()); 48 | } else { 49 | println("File: " + list[i].getCanonicalPath()); 50 | } 51 | } 52 | } 53 | catch(Exception exc) {} 54 | } 55 | 56 | public void onUpdate() { 57 | 58 | } 59 | 60 | private void println(String text) { 61 | print(text + "\r"); 62 | } 63 | 64 | private void print(String text) { 65 | try { 66 | Draw.writeText(text); 67 | } catch(Exception ex) {} 68 | } 69 | 70 | private void clear() { 71 | try { 72 | Draw.eraseDisplay(); 73 | } 74 | catch(Exception exc) {} 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /iLCD/i2c-scanner/App.java: -------------------------------------------------------------------------------- 1 | import ilcd. * ; 2 | import javax.events. * ; 3 | import javax. * ; 4 | import hw. * ; 5 | import comm. * ; 6 | import java.util. * ; 7 | 8 | public class App extends Application implements OnTouchListener { 9 | 10 | public App() throws Exception { 11 | General.resetAll(); 12 | Touch.setTouchFieldReportingEnabled(true); 13 | EventManagement.getTouchEventDispatcher().addListener(this); 14 | Size displaySize = Control.getDisplaySize(); 15 | Touch.setTouchFieldWidth(displaySize.getWidth()); 16 | Touch.setTouchFieldHeight(displaySize.getHeight()); 17 | Touch.createDefineTouchField(1, 0); 18 | scan(); 19 | } 20 | 21 | public void onTouch(TouchEvent event) { 22 | if (event.isTouchPressed()) { 23 | scan(); 24 | } 25 | } 26 | 27 | private void scan() { 28 | clear(); 29 | int devicesCount = 0; 30 | int line = 1; 31 | println("i2c scanner"); 32 | println(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); 33 | print("00: "); 34 | for (int address = 0x03; address < 0x78; address++) { 35 | if (isAvailable(address)) { 36 | print(" "); 37 | if (address < 16) { 38 | print("0"); 39 | } 40 | print(Integer.toHexString(address)); 41 | devicesCount++; 42 | } else { 43 | print(" --"); 44 | } 45 | 46 | if ((address + 1) % 16 == 0) { 47 | println(""); 48 | print(String.valueOf(line)); 49 | print("0:"); 50 | line++; 51 | } 52 | 53 | } 54 | if (devicesCount == 0) { 55 | println("\rNo i2c devices found"); 56 | } else { 57 | println("\rDone, found " + devicesCount + " device/s"); 58 | } 59 | } 60 | 61 | private boolean isAvailable(int address) { 62 | boolean status = false; 63 | try { 64 | I2C i2c = new I2C(address); 65 | int ret = i2c.start(); 66 | if (ret == I2C.OK) { 67 | status = i2c.read() > 0; 68 | } 69 | i2c.stop(); 70 | } catch(Exception exc) {} 71 | return status; 72 | } 73 | 74 | public void onUpdate() { 75 | 76 | } 77 | 78 | private void println(String text) { 79 | print(text + "\r"); 80 | } 81 | 82 | private void print(String text) { 83 | try { 84 | Draw.writeText(text); 85 | } catch(Exception ex) {} 86 | } 87 | 88 | private void clear() { 89 | try { 90 | Draw.eraseDisplay(); 91 | } 92 | catch(Exception exc) {} 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lcd1602-pcf8574-i2c/App.java: -------------------------------------------------------------------------------- 1 | import javax.*; 2 | import comm.*; 3 | import hw.*; 4 | import LcdPcf8574.Config; 5 | import LcdPcf8574; 6 | 7 | public class App extends Application { 8 | 9 | private I2C i2c; 10 | private LcdPcf8574 lcd; 11 | 12 | public App() throws Exception, I2CException { 13 | 14 | i2c = new I2C(0x27, 400000); 15 | 16 | Config config = new Config() { 17 | public void write(byte[] data, int command) { 18 | try { 19 | int ret = i2c.start(); 20 | if (ret == I2C.ERROR) 21 | Console.println("I2C Error"); 22 | if (ret == I2C.TIMEOUT) 23 | Console.println("I2C Timeout"); 24 | if (ret == I2C.OK) { 25 | i2c.write(data, (byte) command); 26 | } 27 | i2c.stop(); 28 | } catch (Exception exc) { 29 | Console.println("write operation - error"); 30 | } 31 | } 32 | }; 33 | lcd = new LcdPcf8574(config); 34 | lcd.begin(16, 2); 35 | lcd.setBacklight(true); 36 | lcd.home(); 37 | } 38 | 39 | public void onUpdate() { 40 | try { 41 | lcd.clear(); 42 | lcd.print("Hi " + IO.getTime()); 43 | delay(1000); 44 | lcd.setCursor(15, 0); 45 | int[] heart = { 46 | 0, 47 | 10, 48 | 31, 49 | 31, 50 | 31, 51 | 14, 52 | 4, 53 | 0 54 | }; 55 | lcd.createChar(0, heart); 56 | lcd.setCursor(15, 0); 57 | lcd.write(0); // write :heart: custom character 58 | 59 | delay(1000); 60 | lcd.setBacklight(false); 61 | delay(400); 62 | lcd.setBacklight(true); 63 | delay(2000); 64 | 65 | lcd.clear(); 66 | lcd.print("Cursor On"); 67 | lcd.cursor(); 68 | delay(2000); 69 | 70 | lcd.clear(); 71 | lcd.print("Cursor Blink"); 72 | lcd.blink(); 73 | delay(2000); 74 | 75 | lcd.clear(); 76 | lcd.print("Cursor OFF"); 77 | lcd.noBlink(); 78 | lcd.noCursor(); 79 | delay(2000); 80 | 81 | lcd.clear(); 82 | lcd.print("Display Off"); 83 | lcd.noDisplay(); 84 | delay(2000); 85 | 86 | lcd.clear(); 87 | lcd.print("Display On"); 88 | lcd.display(); 89 | delay(2000); 90 | 91 | lcd.clear(); 92 | lcd.setCursor(0, 0); 93 | lcd.print("*** first line."); 94 | lcd.setCursor(0, 1); 95 | lcd.print("*** second line."); 96 | delay(2000); 97 | 98 | lcd.scrollDisplayLeft(); 99 | delay(2000); 100 | 101 | lcd.scrollDisplayLeft(); 102 | delay(2000); 103 | 104 | lcd.scrollDisplayLeft(); 105 | delay(2000); 106 | 107 | lcd.scrollDisplayRight(); 108 | delay(2000); 109 | } catch (Exception ex) { 110 | Logger.e(ex.getMessage()); 111 | } 112 | } 113 | 114 | private void delay(int microseconds) { 115 | try { 116 | Thread.sleep(microseconds); 117 | } catch (InterruptedException e) { 118 | Logger.e("Sleep error"); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /bme280-i2c/App.java: -------------------------------------------------------------------------------- 1 | import javax.*; 2 | import comm.*; 3 | import hw.*; 4 | import BME280.Config; 5 | import BME280; 6 | 7 | public class App extends Application { 8 | 9 | private I2C i2c; 10 | private BME280 bme280; 11 | 12 | public App() throws Exception, I2CException { 13 | 14 | i2c = new I2C(0x76, 400000); 15 | 16 | Config config = new Config() { 17 | 18 | public int read(int address) { 19 | return i2cRead(address); 20 | } 21 | 22 | public void read(int address, byte[] buffer, int length) { 23 | i2cRead(address, buffer, length); 24 | } 25 | 26 | public void write(int address, byte command) { 27 | try { 28 | int ret = i2c.start(); 29 | if (ret == I2C.ERROR) 30 | Console.println("I2C Error"); 31 | if (ret == I2C.TIMEOUT) 32 | Console.println("I2C Timeout"); 33 | if (ret == I2C.OK) { 34 | i2c.write(new byte[] { 35 | (byte) command 36 | }, (byte) address); 37 | } 38 | i2c.stop(); 39 | } catch (Exception exc) { 40 | Console.println("write operation - error"); 41 | } 42 | } 43 | }; 44 | bme280 = new BME280(config); 45 | } 46 | 47 | public void onUpdate() { 48 | try { 49 | bme280.calc(); 50 | Logger.log("Temperature in Celsius : " + Math.round(bme280.getTemperature()) + "°C"); 51 | Logger.log("Pressure : " + Math.round(bme280.getPressure()) + " hPa"); 52 | Logger.log("Relative Humidity : " + Math.round(bme280.getHumidity()) + "% RH"); 53 | delay(1000); 54 | } catch (Exception ex) { 55 | Logger.e(ex.getMessage()); 56 | } 57 | } 58 | 59 | int i2cRead(int address) { 60 | byte[] buffer = { 61 | 0 62 | }; 63 | 64 | try { 65 | int ret = i2c.start(); 66 | if (ret == I2C.ERROR) 67 | Console.println("I2C Error"); 68 | if (ret == I2C.TIMEOUT) 69 | Console.println("I2C Timeout"); 70 | if (ret == I2C.OK) { 71 | i2c.write(new byte[] { 72 | (byte) address 73 | }); 74 | 75 | i2c.reStart(); 76 | delay(25); 77 | 78 | i2c.read(buffer); 79 | } 80 | i2c.stop(); 81 | } catch (Exception exc) { 82 | Console.println("write operation - error"); 83 | } 84 | 85 | return buffer[0]; 86 | } 87 | 88 | public void i2cRead(int address, byte[] buffer, int length) { 89 | try { 90 | int ret = i2c.start(); 91 | if (ret == I2C.ERROR) 92 | Console.println("I2C Error"); 93 | if (ret == I2C.TIMEOUT) 94 | Console.println("I2C Timeout"); 95 | if (ret == I2C.OK) { 96 | i2c.write(new byte[] { 97 | (byte) address 98 | }); 99 | 100 | i2c.reStart(); 101 | delay(25); 102 | 103 | i2c.read(buffer, 0, length); 104 | } 105 | i2c.stop(); 106 | } catch (Exception exc) { 107 | Console.println("write operation - error"); 108 | } 109 | } 110 | 111 | private void delay(int microseconds) { 112 | try { 113 | Thread.sleep(microseconds); 114 | } catch (InterruptedException e) { 115 | Logger.e("Sleep error"); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /bme280-i2c/BME280.java: -------------------------------------------------------------------------------- 1 | import hw.Logger; 2 | import java.io.IOException; 3 | 4 | public class BME280 { 5 | 6 | public static final int ADDRESS = 0x76; 7 | // private static final int COMMAND_RESET = 0; 8 | private static final int BME280_REG_ID = 0xD0; 9 | // private static final int BME280_REG_SOFTRESET = 0xE0; 10 | // private static final int BME280_SOFTRESET_VALUE = 0xB6; 11 | 12 | private Config config; 13 | private float temperature; 14 | private float humidity; 15 | private float pressure; 16 | 17 | public BME280(Config config) throws IOException { 18 | this.config = config; 19 | Logger.log("BME280 ID byte: 0x" + Integer.toHexString(read(BME280_REG_ID))); 20 | } 21 | 22 | public void calc() throws Exception { 23 | // Read 24 bytes of data from address 0x88(136) 24 | byte[] b1 = new byte[24]; 25 | 26 | read(0x88, b1); 27 | // Convert the data 28 | // temp coefficients 29 | int dig_T1 = (b1[0] & 0xFF) + ((b1[1] & 0xFF) * 256); 30 | int dig_T2 = (b1[2] & 0xFF) + ((b1[3] & 0xFF) * 256); 31 | if (dig_T2 > 32767) { 32 | dig_T2 -= 65536; 33 | } 34 | int dig_T3 = (b1[4] & 0xFF) + ((b1[5] & 0xFF) * 256); 35 | if (dig_T3 > 32767) { 36 | dig_T3 -= 65536; 37 | } 38 | 39 | // pressure coefficients 40 | int dig_P1 = (b1[6] & 0xFF) + ((b1[7] & 0xFF) * 256); 41 | int dig_P2 = (b1[8] & 0xFF) + ((b1[9] & 0xFF) * 256); 42 | if (dig_P2 > 32767) { 43 | dig_P2 -= 65536; 44 | } 45 | int dig_P3 = (b1[10] & 0xFF) + ((b1[11] & 0xFF) * 256); 46 | if (dig_P3 > 32767) { 47 | dig_P3 -= 65536; 48 | } 49 | int dig_P4 = (b1[12] & 0xFF) + ((b1[13] & 0xFF) * 256); 50 | if (dig_P4 > 32767) { 51 | dig_P4 -= 65536; 52 | } 53 | int dig_P5 = (b1[14] & 0xFF) + ((b1[15] & 0xFF) * 256); 54 | if (dig_P5 > 32767) { 55 | dig_P5 -= 65536; 56 | } 57 | int dig_P6 = (b1[16] & 0xFF) + ((b1[17] & 0xFF) * 256); 58 | if (dig_P6 > 32767) { 59 | dig_P6 -= 65536; 60 | } 61 | int dig_P7 = (b1[18] & 0xFF) + ((b1[19] & 0xFF) * 256); 62 | if (dig_P7 > 32767) { 63 | dig_P7 -= 65536; 64 | } 65 | int dig_P8 = (b1[20] & 0xFF) + ((b1[21] & 0xFF) * 256); 66 | if (dig_P8 > 32767) { 67 | dig_P8 -= 65536; 68 | } 69 | int dig_P9 = (b1[22] & 0xFF) + ((b1[23] & 0xFF) * 256); 70 | if (dig_P9 > 32767) { 71 | dig_P9 -= 65536; 72 | } 73 | // 74 | // // Read 1 byte of data from address 0xA1(161) 75 | int dig_H1 = ((byte) read(0xA1) & 0xFF); 76 | // 77 | // // Read 7 bytes of data from address 0xE1(225) 78 | read(0xE1, b1, 7); 79 | // 80 | // // Convert the data 81 | // // humidity coefficients 82 | int dig_H2 = (b1[0] & 0xFF) + (b1[1] * 256); 83 | if (dig_H2 > 32767) { 84 | dig_H2 -= 65536; 85 | } 86 | int dig_H3 = b1[2] & 0xFF; 87 | int dig_H4 = ((b1[3] & 0xFF) * 16) + (b1[4] & 0xF); 88 | if (dig_H4 > 32767) { 89 | dig_H4 -= 65536; 90 | } 91 | int dig_H5 = ((b1[4] & 0xFF) / 16) + ((b1[5] & 0xFF) * 16); 92 | if (dig_H5 > 32767) { 93 | dig_H5 -= 65536; 94 | } 95 | int dig_H6 = b1[6] & 0xFF; 96 | if (dig_H6 > 127) { 97 | dig_H6 -= 256; 98 | } 99 | 100 | // Select control humidity register 101 | // Humidity over sampling rate = 1 102 | write(0xF2, (byte) 0x01); 103 | // Select control measurement register 104 | // Normal mode, temp and pressure over sampling rate = 1 105 | write(0xF4, (byte) 0x27); 106 | // Select config register 107 | // Stand_by time = 1000 ms 108 | write(0xF5, (byte) 0xA0); 109 | 110 | // Read 8 bytes of data from address 0xF7(247) 111 | // pressure msb1, pressure msb, pressure lsb, temp msb1, temp msb, temp lsb, humidity lsb, humidity msb 112 | byte[] data = new byte[8]; 113 | read(0xF7, data, 8); 114 | 115 | // Convert pressure and temperature data to 19-bits 116 | int adc_p = (((int)(data[0] & 0xFF) * 65536) + ((int)(data[1] & 0xFF) * 256) + (int)(data[2] & 0xF0)) / 16; 117 | int adc_t = (((int)(data[3] & 0xFF) * 65536) + ((int)(data[4] & 0xFF) * 256) + (int)(data[5] & 0xF0)) / 16; 118 | // Convert the humidity data 119 | int adc_h = ((int)(data[6] & 0xFF) * 256 + (int)(data[7] & 0xFF)); 120 | 121 | // Temperature offset calculations 122 | float var1 = (((float) adc_t) / 16384.0f - ((float) dig_T1) / 1024.0f) * ((float) dig_T2); 123 | float var2 = ((((float) adc_t) / 131072.0f - ((float) dig_T1) / 8192.0f) * 124 | (((float) adc_t) / 131072.0f - ((float) dig_T1) / 8192.0f)) * ((float) dig_T3); 125 | float t_fine = (int)(var1 + var2); 126 | float cTemp = (var1 + var2) / 5120.0f; 127 | float fTemp = cTemp * 1.8f + 32; 128 | 129 | // Pressure offset calculations 130 | var1 = (t_fine / 2.0f) - 64000.0f; 131 | var2 = var1 * var1 * ((float) dig_P6) / 32768.0f; 132 | var2 = var2 + var1 * ((float) dig_P5) * 2.0f; 133 | var2 = (var2 / 4.0f) + (((float) dig_P4) * 65536.0f); 134 | var1 = (((float) dig_P3) * var1 * var1 / 524288.0f + ((float) dig_P2) * var1) / 524288.0f; 135 | var1 = (1.0f + var1 / 32768.0f) * ((float) dig_P1); 136 | float p = 1048576.0f - (float) adc_p; 137 | p = (p - (var2 / 4096.0f)) * 6250.0f / var1; 138 | var1 = ((float) dig_P9) * p * p / 2147483648.0f; 139 | var2 = p * ((float) dig_P8) / 32768.0f; 140 | float pressure = (p + (var1 + var2 + ((float) dig_P7)) / 16.0f) / 100; 141 | 142 | // Humidity offset calculations 143 | float var_H = (t_fine - 76800.0f); 144 | var_H = (adc_h - (dig_H4 * 64.0f + dig_H5 / 16384.0f * var_H)) * (dig_H2 / 65536.0f * (1.0f + dig_H6 / 67108864.0f * var_H * (1.0f + dig_H3 / 67108864.0f * var_H))); 145 | float humidity = var_H * (1.0f - dig_H1 * var_H / 524288.0f); 146 | if (humidity > 100.0f) { 147 | humidity = 100.0f; 148 | } else if (humidity < 0.0f) { 149 | humidity = 0.0f; 150 | } 151 | this.temperature = cTemp; //fTemp 152 | this.pressure = pressure; 153 | this.humidity = humidity; 154 | } 155 | 156 | /** 157 | * @return the temperature 158 | */ 159 | public float getTemperature() { 160 | return this.temperature; 161 | } 162 | 163 | /** 164 | * @param temperature the temperature to set 165 | */ 166 | public void setTemperature(float themperature) { 167 | this.temperature = themperature; 168 | } 169 | 170 | /** 171 | * @return the humidity 172 | */ 173 | public float getHumidity() { 174 | return this.humidity; 175 | } 176 | 177 | /** 178 | * @param humidity the humidity to set 179 | */ 180 | public void setHumidity(float humidity) { 181 | this.humidity = humidity; 182 | } 183 | 184 | /** 185 | * @return the pressure 186 | */ 187 | public float getPressure() { 188 | return this.pressure; 189 | } 190 | 191 | /** 192 | * @param pressure the pressure to set 193 | */ 194 | public void setPressure(float pressure) { 195 | this.pressure = pressure; 196 | } 197 | 198 | public void configure(Config config) { 199 | this.config = config; 200 | } 201 | 202 | private int read(int address) throws IOException { 203 | return config.read(address); 204 | } 205 | 206 | private void read(int address, byte[] buffer) throws Exception { 207 | config.read(address, buffer, buffer.length); 208 | } 209 | 210 | private void read(int address, byte[] buffer, int length) throws Exception { 211 | config.read(address, buffer, length); 212 | } 213 | 214 | private void write(int address, byte command) throws IOException { 215 | config.write(address, command); 216 | } 217 | 218 | public interface Config { 219 | int read(int address) throws IOException; 220 | void read(int address, byte[] buffer, int length) throws Exception; 221 | void write(int address, byte command) throws IOException; 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /lcd1602-pcf8574-i2c/LcdPcf8574.java: -------------------------------------------------------------------------------- 1 | import hw.Logger; 2 | import java.io.IOException; 3 | 4 | public class LcdPcf8574 { 5 | 6 | public static final int ADDRESS = 0x27; 7 | 8 | // commands 9 | private static final int LCD_CLEARDISPLAY = 0x01; 10 | private static final int LCD_RETURNHOME = 0x02; 11 | private static final int LCD_ENTRYMODESET = 0x04; 12 | private static final int LCD_DISPLAYCONTROL = 0x08; 13 | private static final int LCD_CURSORSHIFT = 0x10; 14 | private static final int LCD_FUNCTIONSET = 0x20; 15 | private static final int LCD_SETCGRAMADDR = 0x40; 16 | private static final int LCD_SETDDRAMADDR = 0x80; 17 | 18 | // flags for display entry mode 19 | private static final int LCD_ENTRYRIGHT = 0x00; 20 | private static final int LCD_ENTRYLEFT = 0x02; 21 | private static final int LCD_ENTRYSHIFTINCREMENT = 0x01; 22 | private static final int LCD_ENTRYSHIFTDECREMENT = 0x00; 23 | 24 | // flags for display on/off control 25 | private static final int LCD_DISPLAYON = 0x04; 26 | private static final int LCD_DISPLAYOFF = 0x00; 27 | private static final int LCD_CURSORON = 0x02; 28 | private static final int LCD_CURSOROFF = 0x00; 29 | private static final int LCD_BLINKON = 0x01; 30 | private static final int LCD_BLINKOFF = 0x00; 31 | 32 | // flags for display/cursor shift 33 | private static final int LCD_DISPLAYMOVE = 0x08; 34 | private static final int LCD_CURSORMOVE = 0x00; 35 | private static final int LCD_MOVERIGHT = 0x04; 36 | private static final int LCD_MOVELEFT = 0x00; 37 | 38 | // flags for function set 39 | private static final int LCD_8BITMODE = 0x10; 40 | private static final int LCD_4BITMODE = 0x00; 41 | private static final int LCD_2LINE = 0x08; 42 | private static final int LCD_1LINE = 0x00; 43 | private static final int LCD_5x10DOTS = 0x04; 44 | private static final int LCD_5x8DOTS = 0x00; 45 | 46 | private static final int LOW = 0x0; 47 | 48 | // These are Bit-Masks for the special signals and background light 49 | private static final int PCF_RS = 0x01; 50 | private static final int PCF_RW = 0x02; 51 | private static final int PCF_EN = 0x04; 52 | private static final int PCF_BACKLIGHT = 0x08; 53 | 54 | // Definitions on how the PCF8574 is connected to the LCD 55 | // These are Bit-Masks for the special signals and Background 56 | private static final int RSMODE_CMD = 0; 57 | private static final int RSMODE_DATA = 1; 58 | 59 | private boolean backlight; // use backlight 60 | 61 | private byte displayFunction; // lines and dots mode 62 | private byte displayControl; // cursor, display, blink flags 63 | private byte displayMode; // left2right, autoscroll 64 | 65 | private int numLines; // The number of rows the display supports. 66 | 67 | private Config config; 68 | 69 | public LcdPcf8574(Config config) { 70 | this.config = config; 71 | } 72 | 73 | public void configure(Config config) { 74 | this.config = config; 75 | } 76 | 77 | public interface Config { 78 | void write(byte[] data, int command) throws IOException; 79 | } 80 | 81 | public void begin(int cols, int rows) throws IOException { 82 | begin(cols, rows, LCD_5x8DOTS); 83 | } 84 | 85 | public void begin(int cols, int rows, int charsize) throws IOException { 86 | // cols ignored ! 87 | numLines = rows; 88 | 89 | displayFunction = 0; 90 | 91 | if (rows > 1) { 92 | displayFunction |= LCD_2LINE; 93 | } 94 | 95 | // for some 1 line displays you can select a 10 pixel high font 96 | if ((charsize != 0) && (rows == 1)) { 97 | displayFunction |= LCD_5x10DOTS; 98 | } 99 | 100 | // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 101 | // according to datasheet, we need at least 40ms after power rises above 2.7V 102 | // before sending commands. 103 | delayMicroseconds(50); 104 | // initializing th display 105 | write2Wire((byte) 0x00, LOW, false); 106 | delayMicroseconds(50000); 107 | 108 | // put the LCD into 4 bit mode according to the hitachi HD44780 datasheet figure 26, pg 47 109 | sendNibble((byte) 0x03, RSMODE_CMD); 110 | delayMicroseconds(4500); 111 | sendNibble((byte) 0x03, RSMODE_CMD); 112 | delayMicroseconds(4500); 113 | sendNibble((byte) 0x03, RSMODE_CMD); 114 | delayMicroseconds(150); 115 | // finally, set to 4-bit interface 116 | sendNibble((byte) 0x02, RSMODE_CMD); 117 | 118 | // finally, set # lines, font size, etc. 119 | command(LCD_FUNCTIONSET | displayFunction); 120 | 121 | // turn the display on with no cursor or blinking default 122 | displayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 123 | display(); 124 | 125 | // clear it off 126 | clear(); 127 | 128 | // Initialize to default text direction (for romance languages) 129 | displayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 130 | // set the entry mode 131 | command(LCD_ENTRYMODESET | displayMode); 132 | } 133 | 134 | public void clear() throws IOException { 135 | command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero 136 | delayMicroseconds(2000); // this command takes a long time! 137 | } 138 | 139 | public void home() throws IOException { 140 | command(LCD_RETURNHOME); // set cursor position to zero 141 | delayMicroseconds(2000); // this command takes a long time! 142 | } 143 | 144 | // Set the cursor to a new position. 145 | public void setCursor(int col, int row) throws IOException { 146 | int row_offsets[] = {0x00, 0x40, 0x14, 0x54}; 147 | if (row >= numLines) { 148 | row = numLines - 1; // we count rows starting w/0 149 | } 150 | 151 | command(LCD_SETDDRAMADDR | (col + row_offsets[row])); 152 | } 153 | 154 | // Turn the display on/off (quickly) 155 | public void noDisplay() throws IOException { 156 | displayControl &= ~LCD_DISPLAYON; 157 | command(LCD_DISPLAYCONTROL | displayControl); 158 | } 159 | 160 | public void display() throws IOException { 161 | displayControl |= LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 162 | command(LCD_DISPLAYCONTROL | displayControl); 163 | } 164 | 165 | // Turn on and off the blinking cursor 166 | public void noBlink() throws IOException { 167 | displayControl &= ~LCD_BLINKON; 168 | command(LCD_DISPLAYCONTROL | displayControl); 169 | } 170 | 171 | public void blink() throws IOException { 172 | displayControl |= LCD_BLINKON; 173 | command(LCD_DISPLAYCONTROL | displayControl); 174 | } 175 | 176 | // Turns the underline cursor on/off 177 | public void noCursor() throws IOException { 178 | displayControl &= ~LCD_CURSORON; 179 | command(LCD_DISPLAYCONTROL | displayControl); 180 | } 181 | 182 | public void cursor() throws IOException { 183 | displayControl |= LCD_CURSORON; 184 | command(LCD_DISPLAYCONTROL | displayControl); 185 | } 186 | 187 | // These commands scroll the display without changing the RAM 188 | public void scrollDisplayLeft() throws IOException { 189 | command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 190 | } 191 | 192 | public void scrollDisplayRight() throws IOException { 193 | command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 194 | } 195 | 196 | // This is for text that flows Left to Right 197 | public void leftToRight() throws IOException { 198 | displayMode |= LCD_ENTRYLEFT; 199 | command(LCD_ENTRYMODESET | displayMode); 200 | } 201 | 202 | // This is for text that flows Right to Left 203 | public void rightToLeft() throws IOException { 204 | displayMode &= ~LCD_ENTRYLEFT; 205 | command(LCD_ENTRYMODESET | displayMode); 206 | } 207 | 208 | // This will 'right justify' text from the cursor 209 | public void autoscroll() throws IOException { 210 | displayMode |= LCD_ENTRYSHIFTINCREMENT; 211 | command(LCD_ENTRYMODESET | displayMode); 212 | } 213 | 214 | // This will 'left justify' text from the cursor 215 | public void noAutoscroll() throws IOException { 216 | displayMode &= ~LCD_ENTRYSHIFTINCREMENT; 217 | command(LCD_ENTRYMODESET | displayMode); 218 | } 219 | 220 | // Setting the brightness of the background display light. 221 | // The backlight can be switched on and off. 222 | // The current brightness is stored in the private backlight variable to have it available for further data transfers. 223 | public void setBacklight(boolean enable) throws IOException { 224 | backlight = enable; 225 | // send no data but set the background-pin right; 226 | write2Wire((byte) 0x00, RSMODE_DATA, false); 227 | } 228 | 229 | // Allows us to fill the first 8 CGRAM locations with custom characters 230 | public void createChar(int location, int[] charmap) throws IOException { 231 | location &= 0x7; // we only have 8 locations 0-7 232 | command(LCD_SETCGRAMADDR | (location << 3)); 233 | for (int i = 0; i < 8; i++) { 234 | write(charmap[i]); 235 | } 236 | } 237 | 238 | /* The write function is needed for derivation from the Print class. */ 239 | public void write(int value) throws IOException { 240 | send(value, RSMODE_DATA); 241 | } 242 | 243 | public void print(String message) throws IOException { 244 | for (int i = 0; i < message.length(); i++) { 245 | write(message.charAt(i)); 246 | } 247 | } 248 | 249 | // low level functions 250 | private void command(int value) throws IOException { 251 | send(value, RSMODE_CMD); 252 | } 253 | 254 | // write either command or data 255 | private void send(int value, int mode) throws IOException { 256 | // separate the 4 value-nibbles 257 | byte valueLo = (byte) (value & 0x0F); 258 | byte valueHi = (byte) (value >> 4 & 0x0F); 259 | 260 | sendNibble(valueHi, mode); 261 | sendNibble(valueLo, mode); 262 | } 263 | 264 | // write a nibble / halfByte with handshake 265 | private void sendNibble(byte halfByte, int mode) throws IOException { 266 | write2Wire(halfByte, mode, true); 267 | delayMicroseconds(1); // enable pulse must be >450ns 268 | write2Wire(halfByte, mode, false); 269 | delayMicroseconds(37); // commands need > 37us to settle 270 | } 271 | 272 | // private function to change the PCF8674 pins to the given value 273 | private void write2Wire(byte halfByte, int mode, boolean enable) throws IOException { 274 | // map the given values to the hardware of the I2C schema 275 | byte i2cData = (byte) (halfByte << 4); 276 | if (mode > 0) i2cData |= PCF_RS; 277 | // PCF_RW is never used. 278 | if (enable) i2cData |= PCF_EN; 279 | if (backlight) i2cData |= PCF_BACKLIGHT; 280 | config.write(new byte[]{i2cData}, 1); 281 | } 282 | 283 | private void delayMicroseconds(int microseconds) { 284 | try { 285 | Thread.sleep(Math.max(1, Math.round(0.001f * microseconds))); 286 | } catch (InterruptedException e) { 287 | Logger.e("Sleep error"); 288 | } 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /javaino-lcd-keypad-shield/LiquidCrystal.java: -------------------------------------------------------------------------------- 1 | import hw.Logger; 2 | import hw.IO; 3 | import hw.IOException; 4 | import hw.Console; 5 | import hw.Time; 6 | import java.util.List; 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * Liquid crystal driver 11 | * need to improve and fix bugs, 8bit mode not work 12 | */ 13 | public class LiquidCrystal { 14 | 15 | private static final String TAG = "LiquidCrystal library"; 16 | 17 | // commands 18 | private static final byte LCD_CLEARDISPLAY = 0x01; 19 | private static final byte LCD_RETURNHOME = 0x02; 20 | private static final byte LCD_ENTRYMODESET = 0x04; 21 | private static final byte LCD_DISPLAYCONTROL = 0x08; 22 | private static final byte LCD_CURSORSHIFT = 0x10; 23 | private static final byte LCD_FUNCTIONSET = 0x20; 24 | private static final byte LCD_SETCGRAMADDR = 0x40; 25 | private static final short LCD_SETDDRAMADDR = 0x80; 26 | 27 | // flags for display entry mode 28 | private static final byte LCD_ENTRYRIGHT = 0x00; 29 | private static final byte LCD_ENTRYLEFT = 0x02; 30 | private static final byte LCD_ENTRYSHIFTINCREMENT = 0x01; 31 | private static final byte LCD_ENTRYSHIFTDECREMENT = 0x00; 32 | 33 | // flags for display on/off control 34 | private static final byte LCD_DISPLAYON = 0x04; 35 | private static final byte LCD_DISPLAYOFF = 0x00; 36 | private static final byte LCD_CURSORON = 0x02; 37 | private static final byte LCD_CURSOROFF = 0x00; 38 | private static final byte LCD_BLINKON = 0x01; 39 | private static final byte LCD_BLINKOFF = 0x00; 40 | 41 | // flags for display/cursor shift 42 | private static final byte LCD_DISPLAYMOVE = 0x08; 43 | private static final byte LCD_CURSORMOVE = 0x00; 44 | private static final byte LCD_MOVERIGHT = 0x04; 45 | private static final byte LCD_MOVELEFT = 0x00; 46 | 47 | // flags for function set 48 | private static final byte LCD_8BITMODE = 0x10; 49 | private static final byte LCD_4BITMODE = 0x00; 50 | private static final byte LCD_2LINE = 0x08; 51 | private static final byte LCD_1LINE = 0x00; 52 | private static final byte LCD_5x10DOTS = 0x04; 53 | private static final byte LCD_5x8DOTS = 0x00; 54 | 55 | 56 | private boolean backlight; // use backlight 57 | 58 | private byte displayFunction; // lines and dots mode 59 | private byte displayControl; // cursor, display, blink flags 60 | private byte displayMode; // left2right, autoscroll 61 | 62 | private int numLines; // The number of rows the display supports. 63 | 64 | private byte enablePin = 9; 65 | private byte resetPin = 8; 66 | 67 | private static final byte RSMODE_CMD = 0; 68 | private static final byte RSMODE_DATA = 1; 69 | 70 | boolean lcdBitMode = true; // true 4 bit, false 8 bit 71 | 72 | private ArrayList dataBus = new ArrayList(8); 73 | 74 | public LiquidCrystal() throws IOException { 75 | begin(16, 2); 76 | } 77 | 78 | public void begin(int cols, int rows) throws IOException { 79 | begin(cols, rows, LCD_5x8DOTS); 80 | } 81 | 82 | public void begin(int cols, int rows, int charsize) throws IOException { 83 | 84 | if (!lcdBitMode) { 85 | Integer d1 = new Integer(1); 86 | Integer d2 = new Integer(2); 87 | Integer d3 = new Integer(3); 88 | dataBus.add(d1); 89 | dataBus.add(d2); 90 | dataBus.add(d3); 91 | } 92 | Integer d4 = new Integer(4); 93 | Integer d5 = new Integer(5); 94 | Integer d6 = new Integer(6); 95 | Integer d7 = new Integer(7); 96 | dataBus.add(d4); 97 | dataBus.add(d5); 98 | dataBus.add(d6); 99 | dataBus.add(d7); 100 | 101 | if (lcdBitMode) { 102 | dataBus.trimToSize(); 103 | displayFunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 104 | } else { 105 | displayFunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; 106 | } 107 | 108 | // cols ignored ! 109 | numLines = rows; 110 | 111 | // displayFunction = 0; 112 | 113 | if (rows > 1) { 114 | displayFunction |= LCD_2LINE; 115 | } 116 | 117 | // for some 1 line displays you can select a 10 pixel high font 118 | if ((charsize != 0) && (rows == 1)) { 119 | displayFunction |= LCD_5x10DOTS; 120 | } 121 | 122 | // HD44780 123 | // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 124 | // according to datasheet, we need at least 40ms after power rises above 2.7V 125 | // before sending commands. 126 | 127 | for (int i = 0; i < dataBus.size(); ++i) { 128 | IO.setOutput(((Integer) dataBus.get(i)).intValue(), 1); 129 | } 130 | 131 | delay(50000); 132 | IO.setOutput(resetPin, IO.OUTPUT_SET_TO_OFF); 133 | IO.setOutput(enablePin, IO.OUTPUT_SET_TO_OFF); 134 | 135 | if (lcdBitMode) { 136 | write4bits((byte) 0x03); 137 | delay(4500); 138 | write4bits((byte) 0x03); 139 | delay(4500); 140 | write4bits((byte) 0x03); 141 | delay(150); 142 | write4bits((byte) 0x02); 143 | } else { 144 | // this is according to the hitachi HD44780 datasheet 145 | // page 45 figure 23 146 | 147 | // Send function set command sequence 148 | command(LCD_FUNCTIONSET | displayFunction); 149 | delay(4500); // wait more than 4.1ms 150 | 151 | // second try 152 | command(LCD_FUNCTIONSET | displayFunction); 153 | delay(150); 154 | 155 | // third go 156 | command(LCD_FUNCTIONSET | displayFunction); 157 | } 158 | // finally, set # lines, font size, etc. 159 | command(LCD_FUNCTIONSET | displayFunction); 160 | 161 | // turn the display on with no cursor or blinking default 162 | displayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 163 | display(); 164 | 165 | // clear it off 166 | clear(); 167 | 168 | // Initialize to default text direction (for romance languages) 169 | displayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 170 | // set the entry mode 171 | command(LCD_ENTRYMODESET | displayMode); 172 | } 173 | 174 | public void clear() { 175 | command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero 176 | delay(2000); // this command takes a long time! 177 | } 178 | 179 | public void home() { 180 | command(LCD_RETURNHOME); // set cursor position to zero 181 | delay(4); 182 | delay(2000); // this command takes a long time! 183 | } 184 | 185 | // Set the cursor to a new position. 186 | public void setCursor(int col, int row) { 187 | int row_offsets[] = { 188 | 0x00, 189 | 0x40, 190 | 0x14, 191 | 0x54 192 | }; 193 | if (row >= numLines) { 194 | row = numLines - 1; // we count rows starting w/0 195 | } 196 | command(LCD_SETDDRAMADDR | (col + row_offsets[row])); 197 | } 198 | 199 | // Turn the display on/off (quickly) 200 | public void noDisplay() { 201 | displayControl &= ~LCD_DISPLAYON; 202 | command(LCD_DISPLAYCONTROL | displayControl); 203 | } 204 | 205 | public void display() { 206 | displayControl |= LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 207 | command(LCD_DISPLAYCONTROL | displayControl); 208 | } 209 | 210 | // Turn on and off the blinking cursor 211 | public void noBlink() { 212 | displayControl &= ~LCD_BLINKON; 213 | command(LCD_DISPLAYCONTROL | displayControl); 214 | } 215 | 216 | public void blink() { 217 | displayControl |= LCD_BLINKON; 218 | command(LCD_DISPLAYCONTROL | displayControl); 219 | } 220 | 221 | // Turns the underline cursor on/off 222 | public void noCursor() { 223 | displayControl &= ~LCD_CURSORON; 224 | command(LCD_DISPLAYCONTROL | displayControl); 225 | } 226 | 227 | public void cursor() { 228 | displayControl |= LCD_CURSORON; 229 | command(LCD_DISPLAYCONTROL | displayControl); 230 | } 231 | 232 | // These commands scroll the display without changing the RAM 233 | public void scrollDisplayLeft() { 234 | command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 235 | } 236 | 237 | public void scrollDisplayRight() { 238 | command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 239 | } 240 | 241 | // This is for text that flows Left to Right 242 | public void leftToRight() { 243 | displayMode |= LCD_ENTRYLEFT; 244 | command(LCD_ENTRYMODESET | displayMode); 245 | } 246 | 247 | // This is for text that flows Right to Left 248 | public void rightToLeft() { 249 | displayMode &= ~LCD_ENTRYLEFT; 250 | command(LCD_ENTRYMODESET | displayMode); 251 | } 252 | 253 | // This will 'right justify' text from the cursor 254 | public void autoscroll() { 255 | displayMode |= LCD_ENTRYSHIFTINCREMENT; 256 | command(LCD_ENTRYMODESET | displayMode); 257 | } 258 | 259 | // This will 'left justify' text from the cursor 260 | public void noAutoscroll() { 261 | displayMode &= ~LCD_ENTRYSHIFTINCREMENT; 262 | command(LCD_ENTRYMODESET | displayMode); 263 | } 264 | 265 | public void print(String message) { 266 | try { 267 | IO.setOutput(resetPin, RSMODE_DATA); 268 | for (int i = 0; i < message.length(); i++) { 269 | send(message.charAt(i)); 270 | } 271 | } catch (Exception e) { 272 | Logger.e(TAG + " " + e.getMessage()); 273 | } 274 | } 275 | 276 | private void command(int value) { 277 | try { 278 | IO.setOutput(resetPin, RSMODE_CMD); 279 | send(value); 280 | } catch (Exception e) { 281 | Logger.e(TAG + " " + e.getMessage()); 282 | } 283 | } 284 | 285 | // write either command or data 286 | private void send(int value) { 287 | try { 288 | //if ((displayFunction & LCD_4BITMODE) == 0) { // improve me 289 | //if (lcdBitMode) { 290 | write4bits(value); 291 | //} else { 292 | // write8bits(value); 293 | //} 294 | } catch (Exception e) { 295 | Logger.e(TAG + " " + e.getMessage()); 296 | } 297 | } 298 | 299 | private void write4bits(int value) throws IOException { 300 | write(value >> 4); 301 | write(value); 302 | } 303 | 304 | private void write8bits(int value) throws IOException { 305 | write(value); 306 | } 307 | 308 | private void write(int value) throws IOException { 309 | for (int i = 0; i < dataBus.size(); i++) { 310 | IO.setOutput(((Integer) dataBus.get(i)).intValue(), (value >> i) & 0x01); 311 | } 312 | pulseEnable(); 313 | } 314 | 315 | private void pulseEnable() throws IOException { 316 | IO.setOutput(enablePin, IO.OUTPUT_SET_TO_OFF); 317 | delay(1); 318 | IO.setOutput(enablePin, IO.OUTPUT_SET_TO_ON); 319 | delay(1); 320 | IO.setOutput(enablePin, IO.OUTPUT_SET_TO_OFF); 321 | delay(100); 322 | } 323 | 324 | private void delay(int microseconds) { 325 | Time.delay(Math.max(1, Math.round((float) 0.001 * microseconds))); 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------