├── Tiny_altimeter_v1_04 ├── libs │ ├── EEPROM │ │ ├── examples │ │ │ ├── eeprom_clear │ │ │ │ └── eeprom_clear.ino │ │ │ ├── eeprom_write │ │ │ │ └── eeprom_write.ino │ │ │ └── eeprom_read │ │ │ │ └── eeprom_read.ino │ │ ├── keywords.txt │ │ ├── EEPROM.h │ │ └── EEPROM.cpp │ ├── Button │ │ ├── ReadMeArduino1.txt │ │ ├── keywords.txt │ │ ├── Examples │ │ │ ├── Button │ │ │ │ └── Button.ino │ │ │ ├── PollingComplexButton │ │ │ │ └── PollingComplexButton.pde │ │ │ └── EventButton │ │ │ │ └── EventButton.pde │ │ ├── Button.h │ │ ├── AlphaLicense.txt │ │ └── Button.cpp │ ├── BMP180 │ │ ├── keywords.txt │ │ ├── SFE_BMP180.h │ │ ├── examples │ │ │ ├── BMP180_altitude_example │ │ │ │ └── BMP180_altitude_example.ino │ │ │ └── SFE_BMP180_example │ │ │ │ └── SFE_BMP180_example.ino │ │ └── SFE_BMP180.cpp │ ├── Adafruit_GFX │ │ ├── README.txt │ │ ├── license.txt │ │ ├── Adafruit_GFX.h │ │ ├── glcdfont.c │ │ └── Adafruit_GFX.cpp │ └── Adafruit_SSD1306 │ │ ├── README.txt │ │ ├── license.txt │ │ ├── Adafruit_SSD1306.h │ │ ├── examples │ │ ├── ssd1306_128x64_i2c │ │ │ └── ssd1306_128x64_i2c.ino │ │ ├── ssd1306_128x32_i2c │ │ │ └── ssd1306_128x32_i2c.ino │ │ ├── ssd1306_128x32_spi │ │ │ └── ssd1306_128x32_spi.ino │ │ └── ssd1306_128x64_spi │ │ │ └── ssd1306_128x64_spi.ino │ │ └── Adafruit_SSD1306.cpp ├── EEPROMAnything.h ├── Battery.c ├── Symbol.c ├── Splash.c ├── Font24x40.c └── altimetre_oled_bmp180_04.ino ├── README.md └── tiny-altimeter.pde /Tiny_altimeter_v1_04/libs/EEPROM/examples/eeprom_clear/eeprom_clear.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Clear 3 | * 4 | * Sets all of the bytes of the EEPROM to 0. 5 | * This example code is in the public domain. 6 | 7 | */ 8 | 9 | #include 10 | 11 | void setup() 12 | { 13 | // write a 0 to all 512 bytes of the EEPROM 14 | for (int i = 0; i < 512; i++) 15 | EEPROM.write(i, 0); 16 | 17 | // turn the LED on when we're done 18 | digitalWrite(13, HIGH); 19 | } 20 | 21 | void loop() 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/ReadMeArduino1.txt: -------------------------------------------------------------------------------- 1 | ---------------------( COPY )--------------------- 2 | This libraries .h file has been updated by Terry King to make it compatible with Ardino 1.0x (Example 1.03) and also earlier versions like 0023 3 | 4 | #include "WProgram.h" 5 | ...has been replaced by: 6 | 7 | #if defined(ARDUINO) && ARDUINO >= 100 8 | #include "Arduino.h" 9 | #else 10 | #include "WProgram.h" 11 | #endif 12 | 13 | terry@yourduino.com 14 | 02/07/2012 15 | -----------------( END COPY )---------------------- 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/EEPROM/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Ultrasound 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | EEPROM KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | ####################################### 16 | # Constants (LITERAL1) 17 | ####################################### 18 | 19 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/EEPROMAnything.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include // for type definitions 3 | 4 | template int EEPROM_writeAnything(int ee, const T& value) 5 | { 6 | const byte* p = (const byte*)(const void*)&value; 7 | unsigned int i; 8 | for (i = 0; i < sizeof(value); i++) 9 | EEPROM.write(ee++, *p++); 10 | return i; 11 | } 12 | 13 | template int EEPROM_readAnything(int ee, T& value) 14 | { 15 | byte* p = (byte*)(void*)&value; 16 | unsigned int i; 17 | for (i = 0; i < sizeof(value); i++) 18 | *p++ = EEPROM.read(ee++); 19 | return i; 20 | } 21 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/BMP180/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map for SFE_BMP180 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SFE_BMP180 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | startTemperature KEYWORD2 17 | getTemperature KEYWORD2 18 | startPressure KEYWORD2 19 | getPressure KEYWORD2 20 | sealevel KEYWORD2 21 | altitude KEYWORD2 22 | 23 | ####################################### 24 | # Constants (LITERAL1) 25 | ####################################### 26 | 27 | BMP180_ADDR LITERAL1 -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Buttons 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Button KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | isPressed KEYWORD2 16 | wasPressed KEYWORD2 17 | stateChanged KEYWORD2 18 | uniquePress KEYWORD2 19 | pullup KEYWORD2 20 | pulldown KEYWORD2 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | 26 | PULLUP LITERAL1 27 | PULLDOWN LITERAL1 28 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/Examples/Button/Button.ino: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file Button.pde 4 | || @version 1.1 5 | || @author Alexander Brevig 6 | || @contact alexanderbrevig@gmail.com 7 | || 8 | || @description 9 | || | Display the intuitive way of using a button when using this Hardware Abstraction class 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2009 Alexander Brevig. All rights reserved. 14 | || | This code is subject to AlphaLicence.txt 15 | || | alphabeta.alexanderbrevig.com/AlphaLicense.txt 16 | || # 17 | || 18 | */ 19 | 20 | #include 21 | 22 | //create a Button object at pin 12 23 | /* 24 | || Wiring: 25 | || GND -----/ ------ pin 12 26 | */ 27 | Button button = Button(12,PULLUP); 28 | 29 | void setup(){ 30 | pinMode(13,OUTPUT); //debug to led 13 31 | } 32 | 33 | void loop(){ 34 | if(button.isPressed()){ 35 | digitalWrite(13,HIGH); 36 | }else{ 37 | digitalWrite(13,LOW); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_GFX/README.txt: -------------------------------------------------------------------------------- 1 | This is the core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.). It needs to be paired with a hardware-specific library for each display device we carry (to handle the lower-level functions). 2 | 3 | Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 4 | 5 | Written by Limor Fried/Ladyada for Adafruit Industries. 6 | BSD license, check license.txt for more information. 7 | All text above must be included in any redistribution. 8 | 9 | To download, click the DOWNLOAD ZIP button, uncompress and rename the uncompressed folder Adafruit_GFX. Confirm that the Adafruit_GFX folder contains Adafruit_GFX.cpp and Adafruit_GFX.h 10 | 11 | Place the Adafruit_GFX library folder your /Libraries/ folder. You may need to create the Libraries subfolder if its your first library. Restart the IDE. 12 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/EEPROM/examples/eeprom_write/eeprom_write.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Write 3 | * 4 | * Stores values read from analog input 0 into the EEPROM. 5 | * These values will stay in the EEPROM when the board is 6 | * turned off and may be retrieved later by another sketch. 7 | */ 8 | 9 | #include 10 | 11 | // the current address in the EEPROM (i.e. which byte 12 | // we're going to write to next) 13 | int addr = 0; 14 | 15 | void setup() 16 | { 17 | } 18 | 19 | void loop() 20 | { 21 | // need to divide by 4 because analog inputs range from 22 | // 0 to 1023 and each byte of the EEPROM can only hold a 23 | // value from 0 to 255. 24 | int val = analogRead(0) / 4; 25 | 26 | // write the value to the appropriate byte of the EEPROM. 27 | // these values will remain there when the board is 28 | // turned off. 29 | EEPROM.write(addr, val); 30 | 31 | // advance to the next address. there are 512 bytes in 32 | // the EEPROM, so go back to 0 when we hit 512. 33 | addr = addr + 1; 34 | if (addr == 512) 35 | addr = 0; 36 | 37 | delay(100); 38 | } 39 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/EEPROM/examples/eeprom_read/eeprom_read.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Read 3 | * 4 | * Reads the value of each byte of the EEPROM and prints it 5 | * to the computer. 6 | * This example code is in the public domain. 7 | */ 8 | 9 | #include 10 | 11 | // start reading from the first byte (address 0) of the EEPROM 12 | int address = 0; 13 | byte value; 14 | 15 | void setup() 16 | { 17 | // initialize serial and wait for port to open: 18 | Serial.begin(9600); 19 | while (!Serial) { 20 | ; // wait for serial port to connect. Needed for Leonardo only 21 | } 22 | } 23 | 24 | void loop() 25 | { 26 | // read a byte from the current address of the EEPROM 27 | value = EEPROM.read(address); 28 | 29 | Serial.print(address); 30 | Serial.print("\t"); 31 | Serial.print(value, DEC); 32 | Serial.println(); 33 | 34 | // advance to the next address of the EEPROM 35 | address = address + 1; 36 | 37 | // there are only 512 bytes of EEPROM, from 0 to 511, so if we're 38 | // on address 512, wrap around to address 0 39 | if (address == 512) 40 | address = 0; 41 | 42 | delay(500); 43 | } 44 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/EEPROM/EEPROM.h: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM.h - EEPROM library 3 | Copyright (c) 2006 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef EEPROM_h 21 | #define EEPROM_h 22 | 23 | #include 24 | 25 | class EEPROMClass 26 | { 27 | public: 28 | uint8_t read(int); 29 | void write(int, uint8_t); 30 | }; 31 | 32 | extern EEPROMClass EEPROM; 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/Battery.c: -------------------------------------------------------------------------------- 1 | // Battery.c 2 | // Font type : Battery levels (5 icons) 3 | // Font size : 20x28 pixels 4 | // Memory usage : 105 bytes 5 | 6 | #include 7 | 8 | const uint8_t Battery[] PROGMEM={ 9 | 0x7f, 0xff, 0xf0, 10 | 0x40, 0x00, 0x10, 11 | 0xdd, 0xdd, 0xd0, 12 | 0xdd, 0xdd, 0xd0, 13 | 0xdd, 0xdd, 0xd0, 14 | 0x40, 0x00, 0x10, 15 | 0x7f, 0xff, 0xf0, 16 | 0x7f, 0xff, 0xf0, 17 | 0x40, 0x00, 0x10, 18 | 0xc1, 0xdd, 0xd0, 19 | 0xc1, 0xdd, 0xd0, 20 | 0xc1, 0xdd, 0xd0, 21 | 0x40, 0x00, 0x10, 22 | 0x7f, 0xff, 0xf0, 23 | 0x7f, 0xff, 0xf0, 24 | 0x40, 0x00, 0x10, 25 | 0xc0, 0x1d, 0xd0, 26 | 0xc0, 0x1d, 0xd0, 27 | 0xc0, 0x1d, 0xd0, 28 | 0x40, 0x00, 0x10, 29 | 0x7f, 0xff, 0xf0, 30 | 0x7f, 0xff, 0xf0, 31 | 0x40, 0x00, 0x10, 32 | 0xc0, 0x01, 0xd0, 33 | 0xc0, 0x01, 0xd0, 34 | 0xc0, 0x01, 0xd0, 35 | 0x40, 0x00, 0x10, 36 | 0x7f, 0xff, 0xf0, 37 | 0x7f, 0xff, 0xf0, 38 | 0x40, 0x00, 0x10, 39 | 0xc0, 0x00, 0x10, 40 | 0xc0, 0x00, 0x10, 41 | 0xc0, 0x00, 0x10, 42 | 0x40, 0x00, 0x10, 43 | 0x7f, 0xff, 0xf0 44 | }; 45 | 46 | 47 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_SSD1306/README.txt: -------------------------------------------------------------------------------- 1 | This is a library for our Monochrome OLEDs based on SSD1306 drivers 2 | 3 | Pick one up today in the adafruit shop! 4 | ------> http://www.adafruit.com/category/63_98 5 | 6 | These displays use SPI to communicate, 4 or 5 pins are required to 7 | interface 8 | 9 | Adafruit invests time and resources providing this open source code, 10 | please support Adafruit and open-source hardware by purchasing 11 | products from Adafruit! 12 | 13 | Written by Limor Fried/Ladyada for Adafruit Industries. 14 | Scrolling code contributed by Michael Gregg 15 | BSD license, check license.txt for more information 16 | All text above must be included in any redistribution 17 | 18 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_SSD1306. Check that the Adafruit_SSD1306 folder contains Adafruit_SSD1306.cpp and Adafruit_SSD1306.h 19 | 20 | Place the Adafruit_SSD1306 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. 21 | 22 | You will also have to download the Adafruit GFX Graphics core which does all the circles, text, rectangles, etc. You can get it from 23 | https://github.com/adafruit/Adafruit-GFX-Library 24 | and download/install that library as well -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_GFX/license.txt: -------------------------------------------------------------------------------- 1 | Software License Agreement (BSD License) 2 | 3 | Copyright (c) 2012 Adafruit Industries. All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | - Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | - Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_SSD1306/license.txt: -------------------------------------------------------------------------------- 1 | Software License Agreement (BSD License) 2 | 3 | Copyright (c) 2012, Adafruit Industries 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the copyright holders nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The small 128 × 64 OLED display offers good readability even in bright light. It does not consume a lot of energy and seems ideal for outdoor use. Associated with a pressure sensor BMP180 module, it’s relatively easy to achieve a very compact altimeter for hiking. 2 | 3 | Orginal project link: 4 | +https://keeptronic.wordpress.com/2017/01/09/tiny-altimeter/ 5 | 6 | Parts:

7 | Arduino Pro Mini $3.08

8 | Pressure Sensor BMP180 $2.75

9 | Mini 1A Lithium Battery Charging Board Charger Module $1.30

10 | OLED Display 128x64 $4.69

11 | Slide switch (on/off) $1.12

12 | Button $0.65

13 | 200mAh battery $2.99

14 | 15 | 16 | 17 | 18 | 19 | Video review: 20 | https://www.youtube.com/embed/mMiMNTv25Bw 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/Examples/PollingComplexButton/PollingComplexButton.pde: -------------------------------------------------------------------------------- 1 | /** 2 | * PollingComplexButton 3 | * by BREVIG http://alexanderbrevig.com 4 | * 5 | * Use a button connected to digital pin 12. 6 | * Digital pin 12 is used as input and connected to a button 7 | * 8 | * This is similar to EventButton example, but it uses polling technique 9 | */ 10 | 11 | #include 12 | 13 | /* 14 | Wire like this: 15 | GND -----/ button ------ pin 12 16 | */ 17 | Button button = Button(12,BUTTON_PULLUP_INTERNAL); 18 | 19 | /* 20 | Do your regular setup stuff here 21 | */ 22 | void setup() 23 | { 24 | Serial.begin(9800); 25 | pinMode(WLED,OUTPUT); 26 | } 27 | 28 | void loop() 29 | { 30 | button.isPressed(); 31 | if (button.stateChanged()) 32 | { 33 | if (button.wasPressed()) 34 | { 35 | handleButtonPressEvent(); 36 | } 37 | else 38 | { 39 | handleButtonReleaseEvent(); 40 | handleButtonClickEvent(); 41 | } 42 | } 43 | if (button.held(1500)) 44 | { 45 | handleButtonHoldEvent(); 46 | } 47 | } 48 | 49 | 50 | void handleButtonPressEvent() 51 | { 52 | Serial.println("press"); 53 | digitalWrite(WLED,HIGH); 54 | } 55 | 56 | void handleButtonReleaseEvent() 57 | { 58 | Serial.println("release"); 59 | digitalWrite(WLED,LOW); 60 | } 61 | 62 | void handleButtonClickEvent() 63 | { 64 | Serial.println("click"); 65 | digitalWrite(WLED, LOW); 66 | delay(200); 67 | digitalWrite(WLED, HIGH); 68 | delay(200); 69 | digitalWrite(WLED, LOW); 70 | delay(200); 71 | } 72 | 73 | void handleButtonHoldEvent() 74 | { 75 | Serial.println("hold"); 76 | for (int i=0; i<10; i++) 77 | { 78 | digitalWrite(WLED, HIGH); 79 | delay(20); 80 | digitalWrite(WLED, LOW); 81 | delay(20); 82 | } 83 | digitalWrite(WLED, HIGH); 84 | } -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/EEPROM/EEPROM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM.cpp - EEPROM library 3 | Copyright (c) 2006 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /****************************************************************************** 21 | * Includes 22 | ******************************************************************************/ 23 | 24 | #include 25 | #include "Arduino.h" 26 | #include "EEPROM.h" 27 | 28 | /****************************************************************************** 29 | * Definitions 30 | ******************************************************************************/ 31 | 32 | /****************************************************************************** 33 | * Constructors 34 | ******************************************************************************/ 35 | 36 | /****************************************************************************** 37 | * User API 38 | ******************************************************************************/ 39 | 40 | uint8_t EEPROMClass::read(int address) 41 | { 42 | return eeprom_read_byte((unsigned char *) address); 43 | } 44 | 45 | void EEPROMClass::write(int address, uint8_t value) 46 | { 47 | eeprom_write_byte((unsigned char *) address, value); 48 | } 49 | 50 | EEPROMClass EEPROM; 51 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/Examples/EventButton/EventButton.pde: -------------------------------------------------------------------------------- 1 | /** 2 | * EventButton 3 | * by BREVIG http://alexanderbrevig.com 4 | * 5 | * Use a button connected to digital pin 12. 6 | * Digital pin 12 is used as input and connected to a button 7 | * 8 | * Whis example demonstates the event API for buttons 9 | */ 10 | 11 | #include 12 | 13 | /* 14 | Wire like this: 15 | GND -----/ button ------ pin 12 16 | */ 17 | Button button = Button(12,BUTTON_PULLUP_INTERNAL); 18 | 19 | /* 20 | Define the event handler first, this part of the sketch has a "life of it's own" 21 | */ 22 | void handleButtonPressEvents(Button &btn) 23 | { 24 | Serial.println("press"); 25 | digitalWrite(WLED,HIGH); 26 | } 27 | 28 | void handleButtonReleaseEvents(Button &btn) 29 | { 30 | Serial.println("release"); 31 | digitalWrite(WLED,LOW); 32 | } 33 | 34 | void handleButtonClickEvents(Button &btn) 35 | { 36 | Serial.println("click"); 37 | digitalWrite(WLED, LOW); 38 | delay(200); 39 | digitalWrite(WLED, HIGH); 40 | delay(200); 41 | digitalWrite(WLED, LOW); 42 | delay(200); 43 | } 44 | 45 | void handleButtonHoldEvents(Button &btn) 46 | { 47 | Serial.println("hold"); 48 | for (int i=0; i<10; i++) 49 | { 50 | digitalWrite(WLED, HIGH); 51 | delay(20); 52 | digitalWrite(WLED, LOW); 53 | delay(20); 54 | } 55 | digitalWrite(WLED, HIGH); 56 | } 57 | 58 | /* 59 | Do your regular setup stuff here 60 | */ 61 | void setup() 62 | { 63 | Serial.begin(9800); 64 | pinMode(WLED,OUTPUT); 65 | 66 | button.pressHandler(handleButtonPressEvents); 67 | button.releaseHandler(handleButtonReleaseEvents); 68 | button.clickHandler(handleButtonClickEvents); 69 | button.holdHandler(handleButtonHoldEvents,1500); 70 | } 71 | 72 | void loop() 73 | { 74 | button.isPressed(); //update internal state 75 | /* 76 | Feel free to do your own processing here. 77 | The buttons will be handeled 'automagically' by the handler functions 78 | */ 79 | } -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/Button.h: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | || 3 | || @author Alexander Brevig 4 | || @url http://wiring.org.co/ 5 | || @url http://alexanderbrevig.com/ 6 | || @contribution Brett Hagman 7 | || 8 | || @description 9 | || | Hardware Abstraction Library for Buttons. 10 | || | It provides an easy way of handling buttons. 11 | || | 12 | || | Wiring Cross-platform Library 13 | || # 14 | || 15 | || @license Please see cores/Common/License.txt. 16 | || 17 | */ 18 | 19 | #ifndef BUTTON_H 20 | #define BUTTON_H 21 | 22 | #include 23 | 24 | #define BUTTON_PULLUP HIGH 25 | #define BUTTON_PULLUP_INTERNAL 2 26 | #define BUTTON_PULLDOWN LOW 27 | 28 | class Button; 29 | typedef void (*buttonEventHandler)(Button&); 30 | 31 | class Button 32 | { 33 | public: 34 | 35 | Button(uint8_t buttonPin, uint8_t buttonMode = BUTTON_PULLUP_INTERNAL); 36 | 37 | void pullup(uint8_t buttonMode); 38 | void pulldown(); 39 | 40 | bool isPressed(); 41 | bool wasPressed(); 42 | bool stateChanged(); 43 | bool uniquePress(); 44 | 45 | void setHoldThreshold(unsigned int holdTime); 46 | bool held(unsigned int time = 0); 47 | bool heldFor(unsigned int time); 48 | 49 | void pressHandler(buttonEventHandler handler); 50 | void releaseHandler(buttonEventHandler handler); 51 | void clickHandler(buttonEventHandler handler); 52 | void holdHandler(buttonEventHandler handler, unsigned int holdTime = 0); 53 | 54 | unsigned int holdTime() const; 55 | inline unsigned int presses() const 56 | { 57 | return numberOfPresses; 58 | } 59 | 60 | bool operator==(Button &rhs); 61 | 62 | private: 63 | uint8_t pin; 64 | uint8_t mode; 65 | uint8_t state; 66 | unsigned long pressedStartTime; 67 | unsigned int holdEventThreshold; 68 | buttonEventHandler cb_onPress; 69 | buttonEventHandler cb_onRelease; 70 | buttonEventHandler cb_onClick; 71 | buttonEventHandler cb_onHold; 72 | unsigned int numberOfPresses; 73 | bool triggeredHoldEvent; 74 | }; 75 | 76 | #endif 77 | // BUTTON_H -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/Symbol.c: -------------------------------------------------------------------------------- 1 | // Symbol.c 2 | // Font type : Symbols (3 characters) 3 | // Font size : 16x16 pixels 4 | // Memory usage : 96 bytes 5 | 6 | #include 7 | 8 | uint8_t Symbol[] PROGMEM={ 9 | 0x00, 0x00, 10 | 0x00, 0x00, 11 | 0x00, 0x00, 12 | 0x00, 0x00, 13 | 0x00, 0x00, 14 | 0x00, 0x00, 15 | 0x21, 0xc0, 16 | 0x21, 0x20, 17 | 0x21, 0x20, 18 | 0x21, 0x26, 19 | 0x21, 0x29, 20 | 0x39, 0xc1, 21 | 0x25, 0x07, 22 | 0x25, 0x09, 23 | 0x25, 0x09, 24 | 0x25, 0x07, // hPa 25 | 26 | 0x00, 0x00, 27 | 0x00, 0x00, 28 | 0x00, 0x00, 29 | 0x33, 0x8e, 30 | 0x37, 0xdf, 31 | 0x3c, 0xe3, 32 | 0x38, 0xe3, 33 | 0x30, 0xc3, 34 | 0x30, 0xc3, 35 | 0x30, 0xc3, 36 | 0x30, 0xc3, 37 | 0x30, 0xc3, 38 | 0x30, 0xc3, 39 | 0x30, 0xc3, 40 | 0x30, 0xc3, 41 | 0x30, 0xc3, // m 42 | 43 | 0x00, 0x00, 44 | 0x00, 0x00, 45 | 0x00, 0x00, 46 | 0x00, 0x00, 47 | 0x78, 0x3c, 48 | 0xcc, 0x66, 49 | 0xcc, 0xc3, 50 | 0xcc, 0xc3, 51 | 0xcc, 0xc0, 52 | 0x78, 0xc0, 53 | 0x00, 0xc0, 54 | 0x00, 0xc0, 55 | 0x00, 0xc3, 56 | 0x00, 0xc3, 57 | 0x00, 0x66, 58 | 0x00, 0x3c, // °C 59 | 60 | 0x00, 0x00, 61 | 0x01, 0x83, 62 | 0x01, 0x83, 63 | 0x00, 0xc6, 64 | 0x00, 0xc6, 65 | 0x00, 0xc6, 66 | 0x00, 0x6c, 67 | 0xec, 0x6c, 68 | 0xfe, 0x6c, 69 | 0xd6, 0x38, 70 | 0xd6, 0x38, 71 | 0xd6, 0x38, 72 | 0x00, 0x00, 73 | 0x00, 0x00, 74 | 0x00, 0x00, 75 | 0x00, 0x00, // mV 76 | 77 | 0x00, 0x00, 78 | 0x00, 0x00, 79 | 0x00, 0x00, 80 | 0x00, 0x00, 81 | 0x01, 0x00, 82 | 0x03, 0x80, 83 | 0x07, 0xc0, 84 | 0x0f, 0xe0, 85 | 0x1f, 0xf0, 86 | 0x3f, 0xf8, 87 | 0x7f, 0xfc, 88 | 0xff, 0xfe, 89 | 0x00, 0x00, 90 | 0x00, 0x00, 91 | 0x00, 0x00, 92 | 0x00, 0x00, // fleche haut 93 | 94 | 0x00, 0x00, 95 | 0x00, 0x00, 96 | 0x00, 0x00, 97 | 0x00, 0x00, 98 | 0xff, 0xfe, 99 | 0x7f, 0xfc, 100 | 0x3f, 0xf8, 101 | 0x1f, 0xf0, 102 | 0x0f, 0xe0, 103 | 0x07, 0xc0, 104 | 0x03, 0x80, 105 | 0x01, 0x00, 106 | 0x00, 0x00, 107 | 0x00, 0x00, 108 | 0x00, 0x00, 109 | 0x00, 0x00 // fleche bas 110 | }; 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/AlphaLicense.txt: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file AlphaLicense.txt 4 | || @version 1.0 5 | || @author Alexander Brevig 6 | || @contact alexanderbrevig@gmail.com 7 | || 8 | || @description 9 | || | Descripbe the rights and expectations when using my code 10 | || # 11 | || 12 | || @license 13 | || | Copyright (c) 2009 Alexander Brevig. All rights reserved. 14 | || | http://www.gnu.org/licenses/lgpl.html 15 | || # 16 | || 17 | */ 18 | 19 | All content is released into the public domain, under the terms of the GNU LGPL (latest version). 20 | All code is intellectual property, unless stated otherwise. 21 | All usage of my code is permitted, as long as the headers stay intact ( from /* to */ ) or comply to these rules: 22 | *) You are not permitted to change any of these fields, and they should stay as is: 23 | @file 24 | @version 25 | @author 26 | @contact 27 | @licence 28 | *) You are permitted to modify the @description field, remember to update the changelog 29 | *) You are permitted to add these fields 30 | @contribution 31 | This field has to be inserted immediatly after the @contact with a 'blank' line above and below (blank as in '||') 32 | The changelog should indicate what is contributed 33 | @dependencies 34 | This field has to be inserted immediatly after the @description with a 'blank' line above and below (blank as in '||') 35 | @configuration 36 | This field has to be inserted immediatly after the @description or, if existant, the @dependencies with a 'blank' line above and below (blank as in '||') 37 | *) You are permitted and expected to add to the changelog, if changes or contributions are made. 38 | 39 | Example Header (the header to this file modified according to rules) 40 | /* 41 | || 42 | || @file AlphaLicense.txt 43 | || @version 1.0 44 | || @author Alexander Brevig 45 | || @contact alexanderbrevig@gmail.com 46 | || 47 | || @contribution 48 | || | Name Surname - www.domain.com - contact@domain.com 49 | || # 50 | || 51 | || @description 52 | || | Descripbe the rights and expectations when using my code 53 | || # 54 | || 55 | || @dependencies 56 | || | This file depends on the user having accsess to the internet, in order to read the LGPL 57 | || # 58 | || 59 | || @configuration 60 | || | No configuration needed 61 | || # 62 | || 63 | || @license 64 | || | Copyright (c) 2009 Alexander Brevig. All rights reserved. 65 | || | http://www.gnu.org/licenses/lgpl.html 66 | || # 67 | || 68 | */ 69 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_GFX/Adafruit_GFX.h: -------------------------------------------------------------------------------- 1 | #ifndef _ADAFRUIT_GFX_H 2 | #define _ADAFRUIT_GFX_H 3 | 4 | #if ARDUINO >= 100 5 | #include "Arduino.h" 6 | #include "Print.h" 7 | #else 8 | #include "WProgram.h" 9 | #endif 10 | 11 | #define swap(a, b) { int16_t t = a; a = b; b = t; } 12 | 13 | class Adafruit_GFX : public Print { 14 | 15 | public: 16 | 17 | Adafruit_GFX(int16_t w, int16_t h); // Constructor 18 | 19 | // This MUST be defined by the subclass: 20 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; 21 | 22 | // These MAY be overridden by the subclass to provide device-specific 23 | // optimized code. Otherwise 'generic' versions are used. 24 | virtual void 25 | drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color), 26 | drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), 27 | drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), 28 | drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), 29 | fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), 30 | fillScreen(uint16_t color), 31 | invertDisplay(boolean i); 32 | 33 | // These exist only with Adafruit_GFX (no subclass overrides) 34 | void 35 | drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), 36 | drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, 37 | uint16_t color), 38 | fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), 39 | fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, 40 | int16_t delta, uint16_t color), 41 | drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 42 | int16_t x2, int16_t y2, uint16_t color), 43 | fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 44 | int16_t x2, int16_t y2, uint16_t color), 45 | drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, 46 | int16_t radius, uint16_t color), 47 | fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, 48 | int16_t radius, uint16_t color), 49 | drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, 50 | int16_t w, int16_t h, uint16_t color), 51 | drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, 52 | uint16_t bg, uint8_t size), 53 | setCursor(int16_t x, int16_t y), 54 | setTextColor(uint16_t c), 55 | setTextColor(uint16_t c, uint16_t bg), 56 | setTextSize(uint8_t s), 57 | setTextWrap(boolean w), 58 | setRotation(uint8_t r); 59 | 60 | #if ARDUINO >= 100 61 | virtual size_t write(uint8_t); 62 | #else 63 | virtual void write(uint8_t); 64 | #endif 65 | 66 | int16_t 67 | height(void), 68 | width(void); 69 | 70 | uint8_t getRotation(void); 71 | 72 | protected: 73 | const int16_t 74 | WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes 75 | int16_t 76 | _width, _height, // Display w/h as modified by current rotation 77 | cursor_x, cursor_y; 78 | uint16_t 79 | textcolor, textbgcolor; 80 | uint8_t 81 | textsize, 82 | rotation; 83 | boolean 84 | wrap; // If set, 'wrap' text at right edge of display 85 | }; 86 | 87 | #endif // _ADAFRUIT_GFX_H 88 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/BMP180/SFE_BMP180.h: -------------------------------------------------------------------------------- 1 | /* 2 | SFE_BMP180.h 3 | Bosch BMP180 pressure sensor library for the Arduino microcontroller 4 | Mike Grusin, SparkFun Electronics 5 | 6 | Uses floating-point equations from the Weather Station Data Logger project 7 | http://wmrx00.sourceforge.net/ 8 | http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf 9 | 10 | Forked from BMP085 library by M.Grusin 11 | 12 | version 1.0 2013/09/20 initial version 13 | 14 | Our example code uses the "beerware" license. You can do anything 15 | you like with this code. No really, anything. If you find it useful, 16 | buy me a (root) beer someday. 17 | */ 18 | 19 | #ifndef SFE_BMP180_h 20 | #define SFE_BMP180_h 21 | 22 | #if defined(ARDUINO) && ARDUINO >= 100 23 | #include "Arduino.h" 24 | #else 25 | #include "WProgram.h" 26 | #endif 27 | 28 | class SFE_BMP180 29 | { 30 | public: 31 | SFE_BMP180(); // base type 32 | 33 | char begin(); 34 | // call pressure.begin() to initialize BMP180 before use 35 | // returns 1 if success, 0 if failure (bad component or I2C bus shorted?) 36 | 37 | char startTemperature(void); 38 | // command BMP180 to start a temperature measurement 39 | // returns (number of ms to wait) for success, 0 for fail 40 | 41 | char getTemperature(double &T); 42 | // return temperature measurement from previous startTemperature command 43 | // places returned value in T variable (deg C) 44 | // returns 1 for success, 0 for fail 45 | 46 | char startPressure(char oversampling); 47 | // command BMP180 to start a pressure measurement 48 | // oversampling: 0 - 3 for oversampling value 49 | // returns (number of ms to wait) for success, 0 for fail 50 | 51 | char getPressure(double &P, double &T); 52 | // return absolute pressure measurement from previous startPressure command 53 | // note: requires previous temperature measurement in variable T 54 | // places returned value in P variable (mbar) 55 | // returns 1 for success, 0 for fail 56 | 57 | double sealevel(double P, double A); 58 | // convert absolute pressure to sea-level pressure (as used in weather data) 59 | // P: absolute pressure (mbar) 60 | // A: current altitude (meters) 61 | // returns sealevel pressure in mbar 62 | 63 | double altitude(double P, double P0); 64 | // convert absolute pressure to altitude (given baseline pressure; sea-level, runway, etc.) 65 | // P: absolute pressure (mbar) 66 | // P0: fixed baseline pressure (mbar) 67 | // returns signed altitude in meters 68 | 69 | char getError(void); 70 | // If any library command fails, you can retrieve an extended 71 | // error code using this command. Errors are from the wire library: 72 | // 0 = Success 73 | // 1 = Data too long to fit in transmit buffer 74 | // 2 = Received NACK on transmit of address 75 | // 3 = Received NACK on transmit of data 76 | // 4 = Other error 77 | 78 | private: 79 | 80 | char readInt(char address, int &value); 81 | // read an signed int (16 bits) from a BMP180 register 82 | // address: BMP180 register address 83 | // value: external signed int for returned value (16 bits) 84 | // returns 1 for success, 0 for fail, with result in value 85 | 86 | char readUInt(char address, unsigned int &value); 87 | // read an unsigned int (16 bits) from a BMP180 register 88 | // address: BMP180 register address 89 | // value: external unsigned int for returned value (16 bits) 90 | // returns 1 for success, 0 for fail, with result in value 91 | 92 | char readBytes(unsigned char *values, char length); 93 | // read a number of bytes from a BMP180 register 94 | // values: array of char with register address in first location [0] 95 | // length: number of bytes to read back 96 | // returns 1 for success, 0 for fail, with read bytes in values[] array 97 | 98 | char writeBytes(unsigned char *values, char length); 99 | // write a number of bytes to a BMP180 register (and consecutive subsequent registers) 100 | // values: array of char with register address in first location [0] 101 | // length: number of bytes to write 102 | // returns 1 for success, 0 for fail 103 | 104 | int AC1,AC2,AC3,VB1,VB2,MB,MC,MD; 105 | unsigned int AC4,AC5,AC6; 106 | double c5,c6,mc,md,x0,x1,x2,y0,y1,y2,p0,p1,p2; 107 | char _error; 108 | }; 109 | 110 | #define BMP180_ADDR 0x77 // 7-bit address 111 | 112 | #define BMP180_REG_CONTROL 0xF4 113 | #define BMP180_REG_RESULT 0xF6 114 | 115 | #define BMP180_COMMAND_TEMPERATURE 0x2E 116 | #define BMP180_COMMAND_PRESSURE0 0x34 117 | #define BMP180_COMMAND_PRESSURE1 0x74 118 | #define BMP180_COMMAND_PRESSURE2 0xB4 119 | #define BMP180_COMMAND_PRESSURE3 0xF4 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/BMP180/examples/BMP180_altitude_example/BMP180_altitude_example.ino: -------------------------------------------------------------------------------- 1 | /* SFE_BMP180 altitude example sketch 2 | 3 | This sketch shows how to use the Bosch BMP180 pressure sensor 4 | as an altimiter. 5 | https://www.sparkfun.com/products/11824 6 | 7 | Like most pressure sensors, the BMP180 measures absolute pressure. 8 | Since absolute pressure varies with altitude, you can use the pressure 9 | to determine your altitude. 10 | 11 | Because pressure also varies with weather, you must first take a pressure 12 | reading at a known baseline altitude. Then you can measure variations 13 | from that pressure 14 | 15 | Hardware connections: 16 | 17 | - (GND) to GND 18 | + (VDD) to 3.3V 19 | 20 | (WARNING: do not connect + to 5V or the sensor will be damaged!) 21 | 22 | You will also need to connect the I2C pins (SCL and SDA) to your 23 | Arduino. The pins are different on different Arduinos: 24 | 25 | Any Arduino pins labeled: SDA SCL 26 | Uno, Redboard, Pro: A4 A5 27 | Mega2560, Due: 20 21 28 | Leonardo: 2 3 29 | 30 | Leave the IO (VDDIO) pin unconnected. This pin is for connecting 31 | the BMP180 to systems with lower logic levels such as 1.8V 32 | 33 | Have fun! -Your friends at SparkFun. 34 | 35 | The SFE_BMP180 library uses floating-point equations developed by the 36 | Weather Station Data Logger project: http://wmrx00.sourceforge.net/ 37 | 38 | Our example code uses the "beerware" license. You can do anything 39 | you like with this code. No really, anything. If you find it useful, 40 | buy me a beer someday. 41 | 42 | V10 Mike Grusin, SparkFun Electronics 10/24/2013 43 | */ 44 | 45 | // Your sketch must #include this library, and the Wire library. 46 | // (Wire is a standard library included with Arduino.): 47 | 48 | #include 49 | #include 50 | 51 | // You will need to create an SFE_BMP180 object, here called "pressure": 52 | 53 | SFE_BMP180 pressure; 54 | 55 | double baseline; // baseline pressure 56 | 57 | void setup() 58 | { 59 | Serial.begin(9600); 60 | Serial.println("REBOOT"); 61 | 62 | // Initialize the sensor (it is important to get calibration values stored on the device). 63 | 64 | if (pressure.begin()) 65 | Serial.println("BMP180 init success"); 66 | else 67 | { 68 | // Oops, something went wrong, this is usually a connection problem, 69 | // see the comments at the top of this sketch for the proper connections. 70 | 71 | Serial.println("BMP180 init fail (disconnected?)\n\n"); 72 | while(1); // Pause forever. 73 | } 74 | 75 | // Get the baseline pressure: 76 | 77 | baseline = getPressure(); 78 | 79 | Serial.print("baseline pressure: "); 80 | Serial.print(baseline); 81 | Serial.println(" mb"); 82 | } 83 | 84 | void loop() 85 | { 86 | double a,P; 87 | 88 | // Get a new pressure reading: 89 | 90 | P = getPressure(); 91 | 92 | // Show the relative altitude difference between 93 | // the new reading and the baseline reading: 94 | 95 | a = pressure.altitude(P,baseline); 96 | 97 | Serial.print("relative altitude: "); 98 | if (a >= 0.0) Serial.print(" "); // add a space for positive numbers 99 | Serial.print(a,1); 100 | Serial.print(" meters, "); 101 | if (a >= 0.0) Serial.print(" "); // add a space for positive numbers 102 | Serial.print(a*3.28084,0); 103 | Serial.println(" feet"); 104 | 105 | delay(500); 106 | } 107 | 108 | 109 | double getPressure() 110 | { 111 | char status; 112 | double T,P,p0,a; 113 | 114 | // You must first get a temperature measurement to perform a pressure reading. 115 | 116 | // Start a temperature measurement: 117 | // If request is successful, the number of ms to wait is returned. 118 | // If request is unsuccessful, 0 is returned. 119 | 120 | status = pressure.startTemperature(); 121 | if (status != 0) 122 | { 123 | // Wait for the measurement to complete: 124 | 125 | delay(status); 126 | 127 | // Retrieve the completed temperature measurement: 128 | // Note that the measurement is stored in the variable T. 129 | // Use '&T' to provide the address of T to the function. 130 | // Function returns 1 if successful, 0 if failure. 131 | 132 | status = pressure.getTemperature(T); 133 | if (status != 0) 134 | { 135 | // Start a pressure measurement: 136 | // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait). 137 | // If request is successful, the number of ms to wait is returned. 138 | // If request is unsuccessful, 0 is returned. 139 | 140 | status = pressure.startPressure(3); 141 | if (status != 0) 142 | { 143 | // Wait for the measurement to complete: 144 | delay(status); 145 | 146 | // Retrieve the completed pressure measurement: 147 | // Note that the measurement is stored in the variable P. 148 | // Use '&P' to provide the address of P. 149 | // Note also that the function requires the previous temperature measurement (T). 150 | // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.) 151 | // Function returns 1 if successful, 0 if failure. 152 | 153 | status = pressure.getPressure(P,T); 154 | if (status != 0) 155 | { 156 | return(P); 157 | } 158 | else Serial.println("error retrieving pressure measurement\n"); 159 | } 160 | else Serial.println("error starting pressure measurement\n"); 161 | } 162 | else Serial.println("error retrieving temperature measurement\n"); 163 | } 164 | else Serial.println("error starting temperature measurement\n"); 165 | } 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_SSD1306/Adafruit_SSD1306.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is a library for our Monochrome OLEDs based on SSD1306 drivers 3 | 4 | Pick one up today in the adafruit shop! 5 | ------> http://www.adafruit.com/category/63_98 6 | 7 | These displays use SPI to communicate, 4 or 5 pins are required to 8 | interface 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. 15 | BSD license, check license.txt for more information 16 | All text above, and the splash screen must be included in any redistribution 17 | *********************************************************************/ 18 | 19 | #if ARDUINO >= 100 20 | #include "Arduino.h" 21 | #else 22 | #include "WProgram.h" 23 | #endif 24 | 25 | #ifdef __SAM3X8E__ 26 | typedef volatile RwReg PortReg; 27 | typedef uint32_t PortMask; 28 | #else 29 | typedef volatile uint8_t PortReg; 30 | typedef uint8_t PortMask; 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #define BLACK 0 37 | #define WHITE 1 38 | 39 | #define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D 40 | // Address for 128x32 is 0x3C 41 | // Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded) 42 | 43 | /*========================================================================= 44 | SSD1306 Displays 45 | ----------------------------------------------------------------------- 46 | The driver is used in multiple displays (128x64, 128x32, etc.). 47 | Select the appropriate display below to create an appropriately 48 | sized framebuffer, etc. 49 | 50 | SSD1306_128_64 128x64 pixel display 51 | 52 | SSD1306_128_32 128x32 pixel display 53 | 54 | -----------------------------------------------------------------------*/ 55 | #define SSD1306_128_64 56 | // #define SSD1306_128_32 57 | /*=========================================================================*/ 58 | 59 | #if defined SSD1306_128_64 && defined SSD1306_128_32 60 | #error "Only one SSD1306 display can be specified at once in SSD1306.h" 61 | #endif 62 | #if !defined SSD1306_128_64 && !defined SSD1306_128_32 63 | #error "At least one SSD1306 display must be specified in SSD1306.h" 64 | #endif 65 | 66 | #if defined SSD1306_128_64 67 | #define SSD1306_LCDWIDTH 128 68 | #define SSD1306_LCDHEIGHT 64 69 | #endif 70 | #if defined SSD1306_128_32 71 | #define SSD1306_LCDWIDTH 128 72 | #define SSD1306_LCDHEIGHT 32 73 | #endif 74 | 75 | #define SSD1306_SETCONTRAST 0x81 76 | #define SSD1306_DISPLAYALLON_RESUME 0xA4 77 | #define SSD1306_DISPLAYALLON 0xA5 78 | #define SSD1306_NORMALDISPLAY 0xA6 79 | #define SSD1306_INVERTDISPLAY 0xA7 80 | #define SSD1306_DISPLAYOFF 0xAE 81 | #define SSD1306_DISPLAYON 0xAF 82 | 83 | #define SSD1306_SETDISPLAYOFFSET 0xD3 84 | #define SSD1306_SETCOMPINS 0xDA 85 | 86 | #define SSD1306_SETVCOMDETECT 0xDB 87 | 88 | #define SSD1306_SETDISPLAYCLOCKDIV 0xD5 89 | #define SSD1306_SETPRECHARGE 0xD9 90 | 91 | #define SSD1306_SETMULTIPLEX 0xA8 92 | 93 | #define SSD1306_SETLOWCOLUMN 0x00 94 | #define SSD1306_SETHIGHCOLUMN 0x10 95 | 96 | #define SSD1306_SETSTARTLINE 0x40 97 | 98 | #define SSD1306_MEMORYMODE 0x20 99 | #define SSD1306_COLUMNADDR 0x21 100 | #define SSD1306_PAGEADDR 0x22 101 | 102 | #define SSD1306_COMSCANINC 0xC0 103 | #define SSD1306_COMSCANDEC 0xC8 104 | 105 | #define SSD1306_SEGREMAP 0xA0 106 | 107 | #define SSD1306_CHARGEPUMP 0x8D 108 | 109 | #define SSD1306_EXTERNALVCC 0x1 110 | #define SSD1306_SWITCHCAPVCC 0x2 111 | 112 | // Scrolling #defines 113 | #define SSD1306_ACTIVATE_SCROLL 0x2F 114 | #define SSD1306_DEACTIVATE_SCROLL 0x2E 115 | #define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 116 | #define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 117 | #define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 118 | #define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 119 | #define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A 120 | 121 | class Adafruit_SSD1306 : public Adafruit_GFX { 122 | public: 123 | Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS); 124 | Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS); 125 | Adafruit_SSD1306(int8_t RST); 126 | 127 | void begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = SSD1306_I2C_ADDRESS); 128 | void ssd1306_command(uint8_t c); 129 | void ssd1306_data(uint8_t c); 130 | 131 | void clearDisplay(void); 132 | void invertDisplay(uint8_t i); 133 | void display(); 134 | 135 | void startscrollright(uint8_t start, uint8_t stop); 136 | void startscrollleft(uint8_t start, uint8_t stop); 137 | 138 | void startscrolldiagright(uint8_t start, uint8_t stop); 139 | void startscrolldiagleft(uint8_t start, uint8_t stop); 140 | void stopscroll(void); 141 | 142 | void dim(uint8_t contrast); 143 | 144 | void drawPixel(int16_t x, int16_t y, uint16_t color); 145 | 146 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); 147 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); 148 | 149 | private: 150 | int8_t _i2caddr, _vccstate, sid, sclk, dc, rst, cs; 151 | void fastSPIwrite(uint8_t c); 152 | 153 | boolean hwSPI; 154 | PortReg *mosiport, *clkport, *csport, *dcport; 155 | PortMask mosipinmask, clkpinmask, cspinmask, dcpinmask; 156 | 157 | inline void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline)); 158 | inline void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) __attribute__((always_inline)); 159 | 160 | }; 161 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/Splash.c: -------------------------------------------------------------------------------- 1 | // Splash.c 2 | // Font type : Splash Screen 3 | // Font size : 128x64 pixels 4 | // Memory usage : 1024 bytes 5 | 6 | #include 7 | 8 | uint8_t Splash[] PROGMEM={ 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 16 | 0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xc0, 17 | 0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xc0, 18 | 0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x78, 0x01, 0xc0, 19 | 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x20, 0x01, 0xc0, 20 | 0x01, 0xf8, 0x3f, 0x3f, 0xfc, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0, 0x01, 0xc0, 21 | 0x01, 0xf8, 0x3f, 0x3f, 0xfe, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xf0, 0x03, 0xc0, 22 | 0x01, 0xf8, 0x3f, 0x3f, 0xff, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xf8, 0x0f, 0xc0, 23 | 0x01, 0xf8, 0x3f, 0x3f, 0xff, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xfc, 0x0f, 0xc0, 24 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xef, 0x9f, 0xc0, 25 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc7, 0xdf, 0xc0, 26 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x9f, 0xc0, 27 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x3f, 0xc0, 28 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xc0, 29 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x1f, 0xc0, 30 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x78, 0x0f, 0xc0, 31 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x0f, 0xc0, 32 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x0f, 0xc0, 33 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x1f, 0xc0, 34 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0xff, 0xc0, 35 | 0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x09, 0xff, 0xc0, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0xff, 0xc0, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3f, 0xff, 0xc0, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x7f, 0xff, 0xc0, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 46 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 47 | 0xff, 0x00, 0x7c, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 48 | 0xff, 0x00, 0x7c, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 49 | 0xff, 0x00, 0x7c, 0x0e, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 50 | 0xfe, 0x00, 0x7c, 0x0e, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 51 | 0xfe, 0x00, 0x3c, 0x0e, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 52 | 0xfe, 0x00, 0x3c, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 53 | 0xfe, 0x08, 0x3c, 0x0c, 0x01, 0x03, 0x02, 0x06, 0x07, 0xe0, 0x07, 0x80, 0x3c, 0x00, 0xf0, 0x23, 54 | 0xfe, 0x08, 0x3c, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x03, 0xc0, 0x01, 0x80, 0x38, 0x00, 0x30, 0x03, 55 | 0xfc, 0x08, 0x3c, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x03, 0x80, 0x01, 0x80, 0x30, 0x00, 0x30, 0x03, 56 | 0xfc, 0x08, 0x1c, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x03, 0x80, 0x01, 0x80, 0x30, 0x00, 0x30, 0x03, 57 | 0xfc, 0x18, 0x1c, 0x0c, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0x80, 0x30, 0x00, 0x30, 0x3f, 58 | 0xfc, 0x1c, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xc1, 0xc1, 0xf0, 0x38, 0x30, 0x3f, 59 | 0xfc, 0x1c, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xc1, 0xc1, 0xf0, 0x38, 0x30, 0x3f, 60 | 0xfc, 0x1c, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0x81, 0xc1, 0xf0, 0x30, 0x30, 0x3f, 61 | 0xf8, 0x00, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc1, 0xf0, 0x00, 0x30, 0x3f, 62 | 0xf8, 0x00, 0x0c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x80, 0xff, 0xc1, 0xf0, 0x1f, 0xf0, 0x3f, 63 | 0xf8, 0x00, 0x0c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xff, 0xc1, 0xf0, 0x3f, 0xf0, 0x3f, 64 | 0xf8, 0x00, 0x0c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xff, 0xc1, 0xf0, 0x3f, 0xf0, 0x3f, 65 | 0xf8, 0x00, 0x0c, 0x0e, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc0, 0x30, 0x00, 0x30, 0x3f, 66 | 0xf8, 0x1c, 0x0c, 0x0e, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc0, 0x30, 0x00, 0x30, 0x3f, 67 | 0xf0, 0x3c, 0x0c, 0x0e, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc0, 0x30, 0x00, 0x30, 0x3f, 68 | 0xf0, 0x3c, 0x04, 0x0f, 0x01, 0x03, 0x03, 0x03, 0x83, 0xc0, 0x01, 0xe0, 0x38, 0x00, 0x30, 0x3f, 69 | 0xf0, 0x3e, 0x04, 0x0f, 0x81, 0x03, 0x03, 0x03, 0x83, 0xe0, 0x07, 0xf0, 0x3c, 0x00, 0xf0, 0x3f, 70 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 71 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 72 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 73 | }; 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Button/Button.cpp: -------------------------------------------------------------------------------- 1 | /* $Id$ 2 | || 3 | || @author Alexander Brevig 4 | || @url http://wiring.org.co/ 5 | || @url http://alexanderbrevig.com/ 6 | || @contribution Brett Hagman 7 | || 8 | || @description 9 | || | Hardware Abstraction Library for Buttons. 10 | || | It provides an easy way of handling buttons. 11 | || | 12 | || | Wiring Cross-platform Library 13 | || # 14 | || 15 | || @license Please see cores/Common/License.txt. 16 | || 17 | */ 18 | 19 | #include 20 | #include "Button.h" 21 | 22 | #define CURRENT 0 23 | #define PREVIOUS 1 24 | #define CHANGED 2 25 | 26 | /* 27 | || @constructor 28 | || | Set the initial state of this button 29 | || # 30 | || 31 | || @parameter buttonPin sets the pin that this switch is connected to 32 | || @parameter buttonMode indicates BUTTON_PULLUP or BUTTON_PULLDOWN resistor 33 | */ 34 | Button::Button(uint8_t buttonPin, uint8_t buttonMode) 35 | { 36 | pin = buttonPin; 37 | pinMode(pin, INPUT); 38 | 39 | buttonMode == BUTTON_PULLDOWN ? pulldown() : pullup(buttonMode); 40 | state = 0; 41 | bitWrite(state, CURRENT, !mode); 42 | 43 | cb_onPress = 0; 44 | cb_onRelease = 0; 45 | cb_onClick = 0; 46 | cb_onHold = 0; 47 | 48 | numberOfPresses = 0; 49 | triggeredHoldEvent = true; 50 | } 51 | 52 | /* 53 | || @description 54 | || | Prepare logic for a pullup button. 55 | || | If mode is internal set pin HIGH as default 56 | || # 57 | */ 58 | void Button::pullup(uint8_t buttonMode) 59 | { 60 | mode = BUTTON_PULLUP; 61 | if (buttonMode == BUTTON_PULLUP_INTERNAL) 62 | { 63 | digitalWrite(pin, HIGH); 64 | } 65 | } 66 | 67 | /* 68 | || @description 69 | || | Set pin LOW as default 70 | || # 71 | */ 72 | void Button::pulldown(void) 73 | { 74 | mode = BUTTON_PULLDOWN; 75 | } 76 | 77 | /* 78 | || @description 79 | || | Return the bitRead(state,CURRENT) of the switch 80 | || # 81 | || 82 | || @return true if button is pressed 83 | */ 84 | bool Button::isPressed(void) 85 | { 86 | //save the previous value 87 | bitWrite(state, PREVIOUS, bitRead(state, CURRENT)); 88 | 89 | //get the current status of the pin 90 | if (digitalRead(pin) == mode) 91 | { 92 | //currently the button is not pressed 93 | bitWrite(state, CURRENT, false); 94 | } 95 | else 96 | { 97 | //currently the button is pressed 98 | bitWrite(state, CURRENT, true); 99 | } 100 | 101 | //handle state changes 102 | if (bitRead(state, CURRENT) != bitRead(state, PREVIOUS)) 103 | { 104 | //the state changed to PRESSED 105 | if (bitRead(state, CURRENT) == true) 106 | { 107 | numberOfPresses++; 108 | if (cb_onPress) 109 | { 110 | cb_onPress(*this); //fire the onPress event 111 | } 112 | pressedStartTime = millis(); //start timing 113 | triggeredHoldEvent = false; 114 | } 115 | else //the state changed to RELEASED 116 | { 117 | if (cb_onRelease) 118 | { 119 | cb_onRelease(*this); //fire the onRelease event 120 | } 121 | if (cb_onClick) 122 | { 123 | cb_onClick(*this); //fire the onClick event AFTER the onRelease 124 | } 125 | //reset states (for timing and for event triggering) 126 | pressedStartTime = -1; 127 | } 128 | //note that the state changed 129 | bitWrite(state, CHANGED, true); 130 | } 131 | else 132 | { 133 | //note that the state did not change 134 | bitWrite(state, CHANGED, false); 135 | //should we trigger a onHold event? 136 | if (pressedStartTime != -1 && !triggeredHoldEvent) 137 | { 138 | if (millis() - pressedStartTime > holdEventThreshold) 139 | { 140 | if (cb_onHold) 141 | { 142 | cb_onHold(*this); 143 | triggeredHoldEvent = true; 144 | } 145 | } 146 | } 147 | } 148 | return bitRead(state, CURRENT); 149 | } 150 | 151 | /* 152 | || @description 153 | || | Return true if the button has been pressed 154 | || # 155 | */ 156 | bool Button::wasPressed(void) 157 | { 158 | return bitRead(state, CURRENT); 159 | } 160 | 161 | /* 162 | || @description 163 | || | Return true if state has been changed 164 | || # 165 | */ 166 | bool Button::stateChanged(void) 167 | { 168 | return bitRead(state, CHANGED); 169 | } 170 | 171 | /* 172 | || @description 173 | || | Return true if the button is pressed, and was not pressed before 174 | || # 175 | */ 176 | bool Button::uniquePress(void) 177 | { 178 | return (isPressed() && stateChanged()); 179 | } 180 | 181 | /* 182 | || @description 183 | || | onHold polling model 184 | || | Check to see if the button has been pressed for time ms 185 | || | This will clear the counter for next iteration and thus return true once 186 | || # 187 | */ 188 | bool Button::held(unsigned int time /*=0*/) 189 | { 190 | unsigned int threshold = time ? time : holdEventThreshold; //use holdEventThreshold if time == 0 191 | //should we trigger a onHold event? 192 | if (pressedStartTime != -1 && !triggeredHoldEvent) 193 | { 194 | if (millis() - pressedStartTime > threshold) 195 | { 196 | triggeredHoldEvent = true; 197 | return true; 198 | } 199 | } 200 | return false; 201 | } 202 | 203 | /* 204 | || @description 205 | || | Polling model for holding, this is true every check after hold time 206 | || | Check to see if the button has been pressed for time ms 207 | || # 208 | */ 209 | bool Button::heldFor(unsigned int time) 210 | { 211 | if (isPressed()) 212 | { 213 | if (millis() - pressedStartTime > time) 214 | { 215 | return true; 216 | } 217 | } 218 | return false; 219 | } 220 | 221 | /* 222 | || @description 223 | || | Set the hold event time threshold 224 | || # 225 | */ 226 | void Button::setHoldThreshold(unsigned int holdTime) 227 | { 228 | holdEventThreshold = holdTime; 229 | } 230 | 231 | /* 232 | || @description 233 | || | Register a handler for presses on this button 234 | || # 235 | || 236 | || @parameter handler The function to call when this button is pressed 237 | */ 238 | void Button::pressHandler(buttonEventHandler handler) 239 | { 240 | cb_onPress = handler; 241 | } 242 | 243 | /* 244 | || @description 245 | || | Register a handler for releases on this button 246 | || # 247 | || 248 | || @parameter handler The function to call when this button is released 249 | */ 250 | void Button::releaseHandler(buttonEventHandler handler) 251 | { 252 | cb_onRelease = handler; 253 | } 254 | 255 | /* 256 | || @description 257 | || | Register a handler for clicks on this button 258 | || # 259 | || 260 | || @parameter handler The function to call when this button is clicked 261 | */ 262 | void Button::clickHandler(buttonEventHandler handler) 263 | { 264 | cb_onClick = handler; 265 | } 266 | 267 | /* 268 | || @description 269 | || | Register a handler for when this button is held 270 | || # 271 | || 272 | || @parameter handler The function to call when this button is held 273 | */ 274 | void Button::holdHandler(buttonEventHandler handler, unsigned int holdTime /*=0*/) 275 | { 276 | if (holdTime > 0) 277 | { 278 | setHoldThreshold(holdTime); 279 | } 280 | cb_onHold = handler; 281 | } 282 | 283 | /* 284 | || @description 285 | || | Get the time this button has been held 286 | || # 287 | || 288 | || @return The time this button has been held 289 | */ 290 | unsigned int Button::holdTime() const 291 | { 292 | if (pressedStartTime != -1) 293 | { 294 | return millis() - pressedStartTime; 295 | } 296 | else return 0; 297 | } 298 | 299 | /* 300 | || @description 301 | || | Compare a button object against this 302 | || # 303 | || 304 | || @parameter rhs the Button to compare against this Button 305 | || 306 | || @return true if they are the same 307 | */ 308 | bool Button::operator==(Button &rhs) 309 | { 310 | return (this == &rhs); 311 | } 312 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/BMP180/examples/SFE_BMP180_example/SFE_BMP180_example.ino: -------------------------------------------------------------------------------- 1 | /* SFE_BMP180 library example sketch 2 | 3 | This sketch shows how to use the SFE_BMP180 library to read the 4 | Bosch BMP180 barometric pressure sensor. 5 | https://www.sparkfun.com/products/11824 6 | 7 | Like most pressure sensors, the BMP180 measures absolute pressure. 8 | This is the actual ambient pressure seen by the device, which will 9 | vary with both altitude and weather. 10 | 11 | Before taking a pressure reading you must take a temparture reading. 12 | This is done with startTemperature() and getTemperature(). 13 | The result is in degrees C. 14 | 15 | Once you have a temperature reading, you can take a pressure reading. 16 | This is done with startPressure() and getPressure(). 17 | The result is in millibar (mb) aka hectopascals (hPa). 18 | 19 | If you'll be monitoring weather patterns, you will probably want to 20 | remove the effects of altitude. This will produce readings that can 21 | be compared to the published pressure readings from other locations. 22 | To do this, use the sealevel() function. You will need to provide 23 | the known altitude at which the pressure was measured. 24 | 25 | If you want to measure altitude, you will need to know the pressure 26 | at a baseline altitude. This can be average sealevel pressure, or 27 | a previous pressure reading at your altitude, in which case 28 | subsequent altitude readings will be + or - the initial baseline. 29 | This is done with the altitude() function. 30 | 31 | Hardware connections: 32 | 33 | - (GND) to GND 34 | + (VDD) to 3.3V 35 | 36 | (WARNING: do not connect + to 5V or the sensor will be damaged!) 37 | 38 | You will also need to connect the I2C pins (SCL and SDA) to your 39 | Arduino. The pins are different on different Arduinos: 40 | 41 | Any Arduino pins labeled: SDA SCL 42 | Uno, Redboard, Pro: A4 A5 43 | Mega2560, Due: 20 21 44 | Leonardo: 2 3 45 | 46 | Leave the IO (VDDIO) pin unconnected. This pin is for connecting 47 | the BMP180 to systems with lower logic levels such as 1.8V 48 | 49 | Have fun! -Your friends at SparkFun. 50 | 51 | The SFE_BMP180 library uses floating-point equations developed by the 52 | Weather Station Data Logger project: http://wmrx00.sourceforge.net/ 53 | 54 | Our example code uses the "beerware" license. You can do anything 55 | you like with this code. No really, anything. If you find it useful, 56 | buy me a beer someday. 57 | 58 | V10 Mike Grusin, SparkFun Electronics 10/24/2013 59 | */ 60 | 61 | // Your sketch must #include this library, and the Wire library. 62 | // (Wire is a standard library included with Arduino.): 63 | 64 | #include 65 | #include 66 | 67 | // You will need to create an SFE_BMP180 object, here called "pressure": 68 | 69 | SFE_BMP180 pressure; 70 | 71 | #define ALTITUDE 1655.0 // Altitude of SparkFun's HQ in Boulder, CO. in meters 72 | 73 | void setup() 74 | { 75 | Serial.begin(9600); 76 | Serial.println("REBOOT"); 77 | 78 | // Initialize the sensor (it is important to get calibration values stored on the device). 79 | 80 | if (pressure.begin()) 81 | Serial.println("BMP180 init success"); 82 | else 83 | { 84 | // Oops, something went wrong, this is usually a connection problem, 85 | // see the comments at the top of this sketch for the proper connections. 86 | 87 | Serial.println("BMP180 init fail\n\n"); 88 | while(1); // Pause forever. 89 | } 90 | } 91 | 92 | void loop() 93 | { 94 | char status; 95 | double T,P,p0,a; 96 | 97 | // Loop here getting pressure readings every 10 seconds. 98 | 99 | // If you want sea-level-compensated pressure, as used in weather reports, 100 | // you will need to know the altitude at which your measurements are taken. 101 | // We're using a constant called ALTITUDE in this sketch: 102 | 103 | Serial.println(); 104 | Serial.print("provided altitude: "); 105 | Serial.print(ALTITUDE,0); 106 | Serial.print(" meters, "); 107 | Serial.print(ALTITUDE*3.28084,0); 108 | Serial.println(" feet"); 109 | 110 | // If you want to measure altitude, and not pressure, you will instead need 111 | // to provide a known baseline pressure. This is shown at the end of the sketch. 112 | 113 | // You must first get a temperature measurement to perform a pressure reading. 114 | 115 | // Start a temperature measurement: 116 | // If request is successful, the number of ms to wait is returned. 117 | // If request is unsuccessful, 0 is returned. 118 | 119 | status = pressure.startTemperature(); 120 | if (status != 0) 121 | { 122 | // Wait for the measurement to complete: 123 | delay(status); 124 | 125 | // Retrieve the completed temperature measurement: 126 | // Note that the measurement is stored in the variable T. 127 | // Function returns 1 if successful, 0 if failure. 128 | 129 | status = pressure.getTemperature(T); 130 | if (status != 0) 131 | { 132 | // Print out the measurement: 133 | Serial.print("temperature: "); 134 | Serial.print(T,2); 135 | Serial.print(" deg C, "); 136 | Serial.print((9.0/5.0)*T+32.0,2); 137 | Serial.println(" deg F"); 138 | 139 | // Start a pressure measurement: 140 | // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait). 141 | // If request is successful, the number of ms to wait is returned. 142 | // If request is unsuccessful, 0 is returned. 143 | 144 | status = pressure.startPressure(3); 145 | if (status != 0) 146 | { 147 | // Wait for the measurement to complete: 148 | delay(status); 149 | 150 | // Retrieve the completed pressure measurement: 151 | // Note that the measurement is stored in the variable P. 152 | // Note also that the function requires the previous temperature measurement (T). 153 | // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.) 154 | // Function returns 1 if successful, 0 if failure. 155 | 156 | status = pressure.getPressure(P,T); 157 | if (status != 0) 158 | { 159 | // Print out the measurement: 160 | Serial.print("absolute pressure: "); 161 | Serial.print(P,2); 162 | Serial.print(" mb, "); 163 | Serial.print(P*0.0295333727,2); 164 | Serial.println(" inHg"); 165 | 166 | // The pressure sensor returns abolute pressure, which varies with altitude. 167 | // To remove the effects of altitude, use the sealevel function and your current altitude. 168 | // This number is commonly used in weather reports. 169 | // Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m. 170 | // Result: p0 = sea-level compensated pressure in mb 171 | 172 | p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO) 173 | Serial.print("relative (sea-level) pressure: "); 174 | Serial.print(p0,2); 175 | Serial.print(" mb, "); 176 | Serial.print(p0*0.0295333727,2); 177 | Serial.println(" inHg"); 178 | 179 | // On the other hand, if you want to determine your altitude from the pressure reading, 180 | // use the altitude function along with a baseline pressure (sea-level or other). 181 | // Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb. 182 | // Result: a = altitude in m. 183 | 184 | a = pressure.altitude(P,p0); 185 | Serial.print("computed altitude: "); 186 | Serial.print(a,0); 187 | Serial.print(" meters, "); 188 | Serial.print(a*3.28084,0); 189 | Serial.println(" feet"); 190 | } 191 | else Serial.println("error retrieving pressure measurement\n"); 192 | } 193 | else Serial.println("error starting pressure measurement\n"); 194 | } 195 | else Serial.println("error retrieving temperature measurement\n"); 196 | } 197 | else Serial.println("error starting temperature measurement\n"); 198 | 199 | delay(5000); // Pause for 5 seconds. 200 | } 201 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_GFX/glcdfont.c: -------------------------------------------------------------------------------- 1 | #ifndef FONT5X7_H 2 | #define FONT5X7_H 3 | 4 | #ifdef __AVR__ 5 | #include 6 | #include 7 | #else 8 | #define PROGMEM 9 | #endif 10 | 11 | // Standard ASCII 5x7 font 12 | 13 | static const unsigned char font[] PROGMEM = { 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 16 | 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 17 | 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 18 | 0x18, 0x3C, 0x7E, 0x3C, 0x18, 19 | 0x1C, 0x57, 0x7D, 0x57, 0x1C, 20 | 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 21 | 0x00, 0x18, 0x3C, 0x18, 0x00, 22 | 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 23 | 0x00, 0x18, 0x24, 0x18, 0x00, 24 | 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 25 | 0x30, 0x48, 0x3A, 0x06, 0x0E, 26 | 0x26, 0x29, 0x79, 0x29, 0x26, 27 | 0x40, 0x7F, 0x05, 0x05, 0x07, 28 | 0x40, 0x7F, 0x05, 0x25, 0x3F, 29 | 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 30 | 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 31 | 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 32 | 0x14, 0x22, 0x7F, 0x22, 0x14, 33 | 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 34 | 0x06, 0x09, 0x7F, 0x01, 0x7F, 35 | 0x00, 0x66, 0x89, 0x95, 0x6A, 36 | 0x60, 0x60, 0x60, 0x60, 0x60, 37 | 0x94, 0xA2, 0xFF, 0xA2, 0x94, 38 | 0x08, 0x04, 0x7E, 0x04, 0x08, 39 | 0x10, 0x20, 0x7E, 0x20, 0x10, 40 | 0x08, 0x08, 0x2A, 0x1C, 0x08, 41 | 0x08, 0x1C, 0x2A, 0x08, 0x08, 42 | 0x1E, 0x10, 0x10, 0x10, 0x10, 43 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 44 | 0x30, 0x38, 0x3E, 0x38, 0x30, 45 | 0x06, 0x0E, 0x3E, 0x0E, 0x06, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x5F, 0x00, 0x00, 48 | 0x00, 0x07, 0x00, 0x07, 0x00, 49 | 0x14, 0x7F, 0x14, 0x7F, 0x14, 50 | 0x24, 0x2A, 0x7F, 0x2A, 0x12, 51 | 0x23, 0x13, 0x08, 0x64, 0x62, 52 | 0x36, 0x49, 0x56, 0x20, 0x50, 53 | 0x00, 0x08, 0x07, 0x03, 0x00, 54 | 0x00, 0x1C, 0x22, 0x41, 0x00, 55 | 0x00, 0x41, 0x22, 0x1C, 0x00, 56 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 57 | 0x08, 0x08, 0x3E, 0x08, 0x08, 58 | 0x00, 0x80, 0x70, 0x30, 0x00, 59 | 0x08, 0x08, 0x08, 0x08, 0x08, 60 | 0x00, 0x00, 0x60, 0x60, 0x00, 61 | 0x20, 0x10, 0x08, 0x04, 0x02, 62 | 0x3E, 0x51, 0x49, 0x45, 0x3E, 63 | 0x00, 0x42, 0x7F, 0x40, 0x00, 64 | 0x72, 0x49, 0x49, 0x49, 0x46, 65 | 0x21, 0x41, 0x49, 0x4D, 0x33, 66 | 0x18, 0x14, 0x12, 0x7F, 0x10, 67 | 0x27, 0x45, 0x45, 0x45, 0x39, 68 | 0x3C, 0x4A, 0x49, 0x49, 0x31, 69 | 0x41, 0x21, 0x11, 0x09, 0x07, 70 | 0x36, 0x49, 0x49, 0x49, 0x36, 71 | 0x46, 0x49, 0x49, 0x29, 0x1E, 72 | 0x00, 0x00, 0x14, 0x00, 0x00, 73 | 0x00, 0x40, 0x34, 0x00, 0x00, 74 | 0x00, 0x08, 0x14, 0x22, 0x41, 75 | 0x14, 0x14, 0x14, 0x14, 0x14, 76 | 0x00, 0x41, 0x22, 0x14, 0x08, 77 | 0x02, 0x01, 0x59, 0x09, 0x06, 78 | 0x3E, 0x41, 0x5D, 0x59, 0x4E, 79 | 0x7C, 0x12, 0x11, 0x12, 0x7C, 80 | 0x7F, 0x49, 0x49, 0x49, 0x36, 81 | 0x3E, 0x41, 0x41, 0x41, 0x22, 82 | 0x7F, 0x41, 0x41, 0x41, 0x3E, 83 | 0x7F, 0x49, 0x49, 0x49, 0x41, 84 | 0x7F, 0x09, 0x09, 0x09, 0x01, 85 | 0x3E, 0x41, 0x41, 0x51, 0x73, 86 | 0x7F, 0x08, 0x08, 0x08, 0x7F, 87 | 0x00, 0x41, 0x7F, 0x41, 0x00, 88 | 0x20, 0x40, 0x41, 0x3F, 0x01, 89 | 0x7F, 0x08, 0x14, 0x22, 0x41, 90 | 0x7F, 0x40, 0x40, 0x40, 0x40, 91 | 0x7F, 0x02, 0x1C, 0x02, 0x7F, 92 | 0x7F, 0x04, 0x08, 0x10, 0x7F, 93 | 0x3E, 0x41, 0x41, 0x41, 0x3E, 94 | 0x7F, 0x09, 0x09, 0x09, 0x06, 95 | 0x3E, 0x41, 0x51, 0x21, 0x5E, 96 | 0x7F, 0x09, 0x19, 0x29, 0x46, 97 | 0x26, 0x49, 0x49, 0x49, 0x32, 98 | 0x03, 0x01, 0x7F, 0x01, 0x03, 99 | 0x3F, 0x40, 0x40, 0x40, 0x3F, 100 | 0x1F, 0x20, 0x40, 0x20, 0x1F, 101 | 0x3F, 0x40, 0x38, 0x40, 0x3F, 102 | 0x63, 0x14, 0x08, 0x14, 0x63, 103 | 0x03, 0x04, 0x78, 0x04, 0x03, 104 | 0x61, 0x59, 0x49, 0x4D, 0x43, 105 | 0x00, 0x7F, 0x41, 0x41, 0x41, 106 | 0x02, 0x04, 0x08, 0x10, 0x20, 107 | 0x00, 0x41, 0x41, 0x41, 0x7F, 108 | 0x04, 0x02, 0x01, 0x02, 0x04, 109 | 0x40, 0x40, 0x40, 0x40, 0x40, 110 | 0x00, 0x03, 0x07, 0x08, 0x00, 111 | 0x20, 0x54, 0x54, 0x78, 0x40, 112 | 0x7F, 0x28, 0x44, 0x44, 0x38, 113 | 0x38, 0x44, 0x44, 0x44, 0x28, 114 | 0x38, 0x44, 0x44, 0x28, 0x7F, 115 | 0x38, 0x54, 0x54, 0x54, 0x18, 116 | 0x00, 0x08, 0x7E, 0x09, 0x02, 117 | 0x18, 0xA4, 0xA4, 0x9C, 0x78, 118 | 0x7F, 0x08, 0x04, 0x04, 0x78, 119 | 0x00, 0x44, 0x7D, 0x40, 0x00, 120 | 0x20, 0x40, 0x40, 0x3D, 0x00, 121 | 0x7F, 0x10, 0x28, 0x44, 0x00, 122 | 0x00, 0x41, 0x7F, 0x40, 0x00, 123 | 0x7C, 0x04, 0x78, 0x04, 0x78, 124 | 0x7C, 0x08, 0x04, 0x04, 0x78, 125 | 0x38, 0x44, 0x44, 0x44, 0x38, 126 | 0xFC, 0x18, 0x24, 0x24, 0x18, 127 | 0x18, 0x24, 0x24, 0x18, 0xFC, 128 | 0x7C, 0x08, 0x04, 0x04, 0x08, 129 | 0x48, 0x54, 0x54, 0x54, 0x24, 130 | 0x04, 0x04, 0x3F, 0x44, 0x24, 131 | 0x3C, 0x40, 0x40, 0x20, 0x7C, 132 | 0x1C, 0x20, 0x40, 0x20, 0x1C, 133 | 0x3C, 0x40, 0x30, 0x40, 0x3C, 134 | 0x44, 0x28, 0x10, 0x28, 0x44, 135 | 0x4C, 0x90, 0x90, 0x90, 0x7C, 136 | 0x44, 0x64, 0x54, 0x4C, 0x44, 137 | 0x00, 0x08, 0x36, 0x41, 0x00, 138 | 0x00, 0x00, 0x77, 0x00, 0x00, 139 | 0x00, 0x41, 0x36, 0x08, 0x00, 140 | 0x02, 0x01, 0x02, 0x04, 0x02, 141 | 0x3C, 0x26, 0x23, 0x26, 0x3C, 142 | 0x1E, 0xA1, 0xA1, 0x61, 0x12, 143 | 0x3A, 0x40, 0x40, 0x20, 0x7A, 144 | 0x38, 0x54, 0x54, 0x55, 0x59, 145 | 0x21, 0x55, 0x55, 0x79, 0x41, 146 | 0x21, 0x54, 0x54, 0x78, 0x41, 147 | 0x21, 0x55, 0x54, 0x78, 0x40, 148 | 0x20, 0x54, 0x55, 0x79, 0x40, 149 | 0x0C, 0x1E, 0x52, 0x72, 0x12, 150 | 0x39, 0x55, 0x55, 0x55, 0x59, 151 | 0x39, 0x54, 0x54, 0x54, 0x59, 152 | 0x39, 0x55, 0x54, 0x54, 0x58, 153 | 0x00, 0x00, 0x45, 0x7C, 0x41, 154 | 0x00, 0x02, 0x45, 0x7D, 0x42, 155 | 0x00, 0x01, 0x45, 0x7C, 0x40, 156 | 0xF0, 0x29, 0x24, 0x29, 0xF0, 157 | 0xF0, 0x28, 0x25, 0x28, 0xF0, 158 | 0x7C, 0x54, 0x55, 0x45, 0x00, 159 | 0x20, 0x54, 0x54, 0x7C, 0x54, 160 | 0x7C, 0x0A, 0x09, 0x7F, 0x49, 161 | 0x32, 0x49, 0x49, 0x49, 0x32, 162 | 0x32, 0x48, 0x48, 0x48, 0x32, 163 | 0x32, 0x4A, 0x48, 0x48, 0x30, 164 | 0x3A, 0x41, 0x41, 0x21, 0x7A, 165 | 0x3A, 0x42, 0x40, 0x20, 0x78, 166 | 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 167 | 0x39, 0x44, 0x44, 0x44, 0x39, 168 | 0x3D, 0x40, 0x40, 0x40, 0x3D, 169 | 0x3C, 0x24, 0xFF, 0x24, 0x24, 170 | 0x48, 0x7E, 0x49, 0x43, 0x66, 171 | 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 172 | 0xFF, 0x09, 0x29, 0xF6, 0x20, 173 | 0xC0, 0x88, 0x7E, 0x09, 0x03, 174 | 0x20, 0x54, 0x54, 0x79, 0x41, 175 | 0x00, 0x00, 0x44, 0x7D, 0x41, 176 | 0x30, 0x48, 0x48, 0x4A, 0x32, 177 | 0x38, 0x40, 0x40, 0x22, 0x7A, 178 | 0x00, 0x7A, 0x0A, 0x0A, 0x72, 179 | 0x7D, 0x0D, 0x19, 0x31, 0x7D, 180 | 0x26, 0x29, 0x29, 0x2F, 0x28, 181 | 0x26, 0x29, 0x29, 0x29, 0x26, 182 | 0x30, 0x48, 0x4D, 0x40, 0x20, 183 | 0x38, 0x08, 0x08, 0x08, 0x08, 184 | 0x08, 0x08, 0x08, 0x08, 0x38, 185 | 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 186 | 0x2F, 0x10, 0x28, 0x34, 0xFA, 187 | 0x00, 0x00, 0x7B, 0x00, 0x00, 188 | 0x08, 0x14, 0x2A, 0x14, 0x22, 189 | 0x22, 0x14, 0x2A, 0x14, 0x08, 190 | 0xAA, 0x00, 0x55, 0x00, 0xAA, 191 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, 192 | 0x00, 0x00, 0x00, 0xFF, 0x00, 193 | 0x10, 0x10, 0x10, 0xFF, 0x00, 194 | 0x14, 0x14, 0x14, 0xFF, 0x00, 195 | 0x10, 0x10, 0xFF, 0x00, 0xFF, 196 | 0x10, 0x10, 0xF0, 0x10, 0xF0, 197 | 0x14, 0x14, 0x14, 0xFC, 0x00, 198 | 0x14, 0x14, 0xF7, 0x00, 0xFF, 199 | 0x00, 0x00, 0xFF, 0x00, 0xFF, 200 | 0x14, 0x14, 0xF4, 0x04, 0xFC, 201 | 0x14, 0x14, 0x17, 0x10, 0x1F, 202 | 0x10, 0x10, 0x1F, 0x10, 0x1F, 203 | 0x14, 0x14, 0x14, 0x1F, 0x00, 204 | 0x10, 0x10, 0x10, 0xF0, 0x00, 205 | 0x00, 0x00, 0x00, 0x1F, 0x10, 206 | 0x10, 0x10, 0x10, 0x1F, 0x10, 207 | 0x10, 0x10, 0x10, 0xF0, 0x10, 208 | 0x00, 0x00, 0x00, 0xFF, 0x10, 209 | 0x10, 0x10, 0x10, 0x10, 0x10, 210 | 0x10, 0x10, 0x10, 0xFF, 0x10, 211 | 0x00, 0x00, 0x00, 0xFF, 0x14, 212 | 0x00, 0x00, 0xFF, 0x00, 0xFF, 213 | 0x00, 0x00, 0x1F, 0x10, 0x17, 214 | 0x00, 0x00, 0xFC, 0x04, 0xF4, 215 | 0x14, 0x14, 0x17, 0x10, 0x17, 216 | 0x14, 0x14, 0xF4, 0x04, 0xF4, 217 | 0x00, 0x00, 0xFF, 0x00, 0xF7, 218 | 0x14, 0x14, 0x14, 0x14, 0x14, 219 | 0x14, 0x14, 0xF7, 0x00, 0xF7, 220 | 0x14, 0x14, 0x14, 0x17, 0x14, 221 | 0x10, 0x10, 0x1F, 0x10, 0x1F, 222 | 0x14, 0x14, 0x14, 0xF4, 0x14, 223 | 0x10, 0x10, 0xF0, 0x10, 0xF0, 224 | 0x00, 0x00, 0x1F, 0x10, 0x1F, 225 | 0x00, 0x00, 0x00, 0x1F, 0x14, 226 | 0x00, 0x00, 0x00, 0xFC, 0x14, 227 | 0x00, 0x00, 0xF0, 0x10, 0xF0, 228 | 0x10, 0x10, 0xFF, 0x10, 0xFF, 229 | 0x14, 0x14, 0x14, 0xFF, 0x14, 230 | 0x10, 0x10, 0x10, 0x1F, 0x00, 231 | 0x00, 0x00, 0x00, 0xF0, 0x10, 232 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 233 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 234 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 236 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 237 | 0x38, 0x44, 0x44, 0x38, 0x44, 238 | 0x7C, 0x2A, 0x2A, 0x3E, 0x14, 239 | 0x7E, 0x02, 0x02, 0x06, 0x06, 240 | 0x02, 0x7E, 0x02, 0x7E, 0x02, 241 | 0x63, 0x55, 0x49, 0x41, 0x63, 242 | 0x38, 0x44, 0x44, 0x3C, 0x04, 243 | 0x40, 0x7E, 0x20, 0x1E, 0x20, 244 | 0x06, 0x02, 0x7E, 0x02, 0x02, 245 | 0x99, 0xA5, 0xE7, 0xA5, 0x99, 246 | 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 247 | 0x4C, 0x72, 0x01, 0x72, 0x4C, 248 | 0x30, 0x4A, 0x4D, 0x4D, 0x30, 249 | 0x30, 0x48, 0x78, 0x48, 0x30, 250 | 0xBC, 0x62, 0x5A, 0x46, 0x3D, 251 | 0x3E, 0x49, 0x49, 0x49, 0x00, 252 | 0x7E, 0x01, 0x01, 0x01, 0x7E, 253 | 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 254 | 0x44, 0x44, 0x5F, 0x44, 0x44, 255 | 0x40, 0x51, 0x4A, 0x44, 0x40, 256 | 0x40, 0x44, 0x4A, 0x51, 0x40, 257 | 0x00, 0x00, 0xFF, 0x01, 0x03, 258 | 0xE0, 0x80, 0xFF, 0x00, 0x00, 259 | 0x08, 0x08, 0x6B, 0x6B, 0x08, 260 | 0x36, 0x12, 0x36, 0x24, 0x36, 261 | 0x06, 0x0F, 0x09, 0x0F, 0x06, 262 | 0x00, 0x00, 0x18, 0x18, 0x00, 263 | 0x00, 0x00, 0x10, 0x10, 0x00, 264 | 0x30, 0x40, 0xFF, 0x01, 0x01, 265 | 0x00, 0x1F, 0x01, 0x01, 0x1E, 266 | 0x00, 0x19, 0x1D, 0x17, 0x12, 267 | 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 268 | 0x00, 0x00, 0x00, 0x00, 0x00 269 | }; 270 | #endif // FONT5X7_H 271 | -------------------------------------------------------------------------------- /tiny-altimeter.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "EEPROMAnything.h" 9 | 10 | // If using software SPI (the default case): 11 | #define OLED_MOSI 9 12 | #define OLED_CLK 10 13 | #define OLED_DC 11 14 | #define OLED_CS 12 15 | #define OLED_RESET 13 16 | 17 | #define BUTTON1_PIN 4 18 | 19 | #define HPA 0 20 | #define METER 1 21 | #define DEG 2 22 | 23 | Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 24 | 25 | /* Uncomment this block to use hardware SPI 26 | #define OLED_DC 6 27 | #define OLED_CS 7 28 | #define OLED_RESET 8 29 | Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); 30 | */ 31 | 32 | extern uint8_t Font24x40[]; 33 | extern uint8_t Symbol[]; 34 | extern uint8_t Spash[]; 35 | 36 | SFE_BMP180 pressure; 37 | Button button1 = Button(BUTTON1_PIN,BUTTON_PULLDOWN); 38 | boolean longPush = false; 39 | int value, etat = 0; 40 | double QNH, saveQNH; 41 | double temperature, pression, altitude = 0; 42 | double baseAltitude, saveBaseAltitude = 0; 43 | double altiMin = 9999.0; 44 | double altiMax = 0.0; 45 | double lastValue = 0.0; 46 | int eepromAddr = 10; 47 | 48 | #define MAX_SAMPLES 20 49 | double samplesBuffer[MAX_SAMPLES]; 50 | int indexBfr = 0; 51 | double averagePressure = 0; 52 | boolean bufferReady = false; 53 | int screen = 0; // numero d'ecran 54 | #define NB_SCREENS 5 55 | String debugMsg; 56 | 57 | /* ------------------------------------ setup ------------------------------------------ */ 58 | void setup() { 59 | button1.releaseHandler(handleButtonReleaseEvents); 60 | button1.holdHandler(handleButtonHoldEvents,2000); 61 | 62 | display.begin(SSD1306_SWITCHCAPVCC); 63 | 64 | // init QNH 65 | EEPROM_readAnything(eepromAddr, QNH); 66 | if (isnan(QNH)) { 67 | QNH = 1013.25; 68 | EEPROM_writeAnything(eepromAddr, QNH); // QNH standard 69 | } 70 | saveQNH = QNH; 71 | 72 | display.clearDisplay(); 73 | display.drawBitmap(0, 0, Spash, 128, 64, 1); 74 | display.display(); 75 | delay(1000); 76 | display.clearDisplay(); 77 | display.setTextSize(1); 78 | display.setTextColor(WHITE); 79 | display.setCursor(0,0); 80 | if (!pressure.begin()) { 81 | display.println("Init fail !"); 82 | display.println("Turn OFF"); 83 | display.display(); 84 | while(1); // Pause forever. 85 | } 86 | 87 | button1.isPressed(); 88 | screen = 1; 89 | } 90 | 91 | /* ------------------------------------ loop ------------------------------------------ */ 92 | void loop() { 93 | char status; 94 | 95 | button1.isPressed(); 96 | 97 | // get pressure and temperature and calculate altitude 98 | status = pressure.startTemperature(); 99 | if (status != 0) { 100 | delay(status); 101 | status = pressure.getTemperature(temperature); 102 | if (status != 0) { 103 | status = pressure.startPressure(0); 104 | if (status != 0) { 105 | delay(status); 106 | status = pressure.getPressure(pression, temperature); 107 | if (status != 0) { 108 | savePressureSample(pression); 109 | averagePressure = getPressureAverage(); 110 | if (bufferReady) { 111 | altitude = pressure.altitude(averagePressure*100, QNH*100); 112 | setAltiMinMax(); 113 | } 114 | 115 | } 116 | } 117 | } 118 | } 119 | 120 | if (etat == 0) { 121 | // init baseAltitude 122 | if (baseAltitude == 0) { 123 | baseAltitude = round(altitude); 124 | saveBaseAltitude = baseAltitude; 125 | } 126 | // calculate QNH 127 | if (baseAltitude != saveBaseAltitude) { 128 | QNH = pressure.sealevel(pression, baseAltitude); 129 | saveBaseAltitude = baseAltitude; 130 | } 131 | // Save QNH in EEPROM 132 | if (QNH != saveQNH) { 133 | saveQNH = QNH; 134 | EEPROM_writeAnything(eepromAddr, QNH); 135 | } 136 | 137 | switch (screen) { 138 | case 1: // Altitude 139 | if (lastValue != altitude) { 140 | showScreen("ALTITUDE", altitude, METER); 141 | lastValue = altitude; 142 | } 143 | break; 144 | 145 | case 2: // Altitude Max 146 | if (lastValue != altiMax) { 147 | showScreen("ALTITUDE MAX", altiMax, METER); 148 | lastValue = altiMax; 149 | } 150 | break; 151 | 152 | case 3: // Altitude Min 153 | if (lastValue != altiMin) { 154 | showScreen("ALTITUDE MIN", altiMin, METER); 155 | lastValue = altiMin; 156 | } 157 | break; 158 | 159 | case 4: // Pression 160 | if (lastValue != pression) { 161 | showScreen("PRESSION", pression, HPA); 162 | lastValue = pression; 163 | } 164 | break; 165 | 166 | case 5: // Temperature 167 | if (lastValue != temperature) { 168 | showScreen("TEMPERATURE", temperature, DEG); 169 | lastValue = temperature; 170 | } 171 | break; 172 | } 173 | } 174 | else { // Settings 175 | // Settings 176 | display.clearDisplay(); 177 | display.setTextSize(1); 178 | display.setCursor(0,0); 179 | display.println("CALIBRATION"); 180 | display.setCursor(0,15); 181 | display.print("QNH : "); 182 | display.print(QNH,2); 183 | display.println(" hPa"); 184 | //display.print("Debug : "); 185 | //display.println(debugMsg); 186 | //display.print("Etat : "); 187 | //display.println(etat); 188 | if (etat == 1) drawSymbol(100, 40, 3); //UP 189 | if (etat == 2) drawSymbol(100, 40, 4); // DOWN 190 | if (value != 0) { 191 | baseAltitude += value; 192 | value = 0; 193 | // recalcule le QNH 194 | QNH = pressure.sealevel(pression, baseAltitude); 195 | } 196 | display.setCursor(0,45); 197 | display.print("Alti : "); 198 | display.println(baseAltitude, 0); 199 | display.display(); 200 | } 201 | 202 | delay(50); 203 | } 204 | /* -------------------- functions -------------------- */ 205 | 206 | // Display screen data 207 | void showScreen(String label, double value, int unit) { 208 | display.clearDisplay(); 209 | display.setCursor(0,0); 210 | display.println(label); 211 | drawFloatValue(0, 20, value, unit); 212 | display.display(); 213 | } 214 | 215 | // Saves sample pressure 216 | void savePressureSample(float pressure) { 217 | if (indexBfr == MAX_SAMPLES) { 218 | indexBfr = 0; 219 | bufferReady = true; 220 | } 221 | samplesBuffer[indexBfr++] = pressure; 222 | } 223 | 224 | // Returns the average pressure samples 225 | float getPressureAverage() { 226 | double sum = 0; 227 | for (int i =0; i altiMax) altiMax = altitude; 236 | if (altitude < altiMin) altiMin = altitude; 237 | } 238 | void resetAltiMinMax() { 239 | altiMax = altiMin = altitude; 240 | } 241 | // Management release the button 242 | void handleButtonReleaseEvents(Button &btn) { 243 | //debugMsg = "Release"; 244 | if (!longPush) { 245 | if (etat != 0 ) { // Settings 246 | if (etat == 1) value = 1; 247 | if (etat == 2) value = -1; 248 | } 249 | else { // Change screen 250 | screen++; 251 | if (screen > NB_SCREENS) screen = 1; 252 | lastValue = 0; 253 | } 254 | } 255 | longPush = false; 256 | } 257 | 258 | // Management support extended on the button 259 | void handleButtonHoldEvents(Button &btn) { 260 | //debugMsg = "Hold"; 261 | longPush = true; 262 | screen = 1; 263 | value = 0; 264 | if (screen == 1 && ++etat > 2) { 265 | etat = 0; 266 | delay(500); 267 | } 268 | else if (screen == 2 || screen == 3) { 269 | resetAltiMinMax(); 270 | } 271 | } 272 | 273 | // Displays a character x, y 274 | void drawCar(int sx, int sy, int num, uint8_t *font, int fw, int fh, int color) { 275 | byte row; 276 | for(int y=0; y 5) { // pas de decimal 307 | for (int n=0; n<4; n++) drawBigCar(sx+n*26, sy, charBuf[n]- '0'); 308 | drawSymbol(108,sy, unit); 309 | } 310 | else { 311 | drawBigCar(sx+86, sy, charBuf[nbCar-1]- '0'); 312 | drawDot(78, sy+39, 6); 313 | nbCar--; 314 | if (--nbCar > 0) drawBigCar(sx+52, sy, charBuf[nbCar-1]- '0'); 315 | if (--nbCar > 0) drawBigCar(sx+26, sy, charBuf[nbCar-1]- '0'); 316 | if (--nbCar > 0) drawBigCar(sx, sy, charBuf[nbCar-1]- '0'); 317 | drawSymbol(112,sy, unit); 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/Font24x40.c: -------------------------------------------------------------------------------- 1 | // Font24x40.c 2 | // Font type : Numeric (10 characters) 3 | // Font size : 24x40 pixels 4 | // Memory usage : 720 bytes 5 | 6 | #include 7 | 8 | uint8_t Font24x40[] PROGMEM={ 9 | 0x00, 0x3e, 0x00, 10 | 0x00, 0xff, 0x80, 11 | 0x03, 0xff, 0xe0, 12 | 0x03, 0xff, 0xe0, 13 | 0x07, 0xff, 0xf0, 14 | 0x0f, 0xff, 0xf8, 15 | 0x0f, 0xe3, 0xf8, 16 | 0x1f, 0xc1, 0xfc, 17 | 0x1f, 0x80, 0xfc, 18 | 0x1f, 0x80, 0xfc, 19 | 0x1f, 0x80, 0xfc, 20 | 0x1f, 0x00, 0x7c, 21 | 0x3f, 0x00, 0x7e, 22 | 0x3f, 0x00, 0x7e, 23 | 0x3f, 0x00, 0x7e, 24 | 0x3f, 0x00, 0x7e, 25 | 0x3f, 0x00, 0x7e, 26 | 0x3f, 0x00, 0x7e, 27 | 0x3f, 0x00, 0x7e, 28 | 0x3f, 0x00, 0x7e, 29 | 0x3f, 0x00, 0x7e, 30 | 0x3f, 0x00, 0x7e, 31 | 0x3f, 0x00, 0x7e, 32 | 0x3f, 0x00, 0x7e, 33 | 0x3f, 0x00, 0x7e, 34 | 0x3f, 0x00, 0x7e, 35 | 0x3f, 0x00, 0x7e, 36 | 0x3f, 0x00, 0x7e, 37 | 0x1f, 0x00, 0x7c, 38 | 0x1f, 0x80, 0xfc, 39 | 0x1f, 0x80, 0xfc, 40 | 0x1f, 0x80, 0xfc, 41 | 0x1f, 0xc1, 0xfc, 42 | 0x0f, 0xe3, 0xf8, 43 | 0x0f, 0xff, 0xf8, 44 | 0x07, 0xff, 0xf0, 45 | 0x03, 0xff, 0xe0, 46 | 0x03, 0xff, 0xe0, 47 | 0x00, 0xff, 0x80, 48 | 0x00, 0x3e, 0x00, // 0 49 | 50 | 0x00, 0x07, 0xc0, 51 | 0x00, 0x07, 0xc0, 52 | 0x00, 0x0f, 0xc0, 53 | 0x00, 0x0f, 0xc0, 54 | 0x00, 0x1f, 0xc0, 55 | 0x00, 0x3f, 0xc0, 56 | 0x00, 0x3f, 0xc0, 57 | 0x00, 0x7f, 0xc0, 58 | 0x00, 0xff, 0xc0, 59 | 0x03, 0xff, 0xc0, 60 | 0x07, 0xff, 0xc0, 61 | 0x0f, 0xff, 0xc0, 62 | 0x0f, 0xef, 0xc0, 63 | 0x0f, 0xcf, 0xc0, 64 | 0x0f, 0x0f, 0xc0, 65 | 0x0e, 0x0f, 0xc0, 66 | 0x08, 0x0f, 0xc0, 67 | 0x00, 0x0f, 0xc0, 68 | 0x00, 0x0f, 0xc0, 69 | 0x00, 0x0f, 0xc0, 70 | 0x00, 0x0f, 0xc0, 71 | 0x00, 0x0f, 0xc0, 72 | 0x00, 0x0f, 0xc0, 73 | 0x00, 0x0f, 0xc0, 74 | 0x00, 0x0f, 0xc0, 75 | 0x00, 0x0f, 0xc0, 76 | 0x00, 0x0f, 0xc0, 77 | 0x00, 0x0f, 0xc0, 78 | 0x00, 0x0f, 0xc0, 79 | 0x00, 0x0f, 0xc0, 80 | 0x00, 0x0f, 0xc0, 81 | 0x00, 0x0f, 0xc0, 82 | 0x00, 0x0f, 0xc0, 83 | 0x00, 0x0f, 0xc0, 84 | 0x00, 0x0f, 0xc0, 85 | 0x00, 0x0f, 0xc0, 86 | 0x00, 0x0f, 0xc0, 87 | 0x00, 0x0f, 0xc0, 88 | 0x00, 0x0f, 0xc0, 89 | 0x00, 0x00, 0x00, // 1 90 | 91 | 0x00, 0x7f, 0x00, 92 | 0x01, 0xff, 0xc0, 93 | 0x03, 0xff, 0xf0, 94 | 0x07, 0xff, 0xf8, 95 | 0x0f, 0xff, 0xf8, 96 | 0x1f, 0xff, 0xfc, 97 | 0x1f, 0xc1, 0xfc, 98 | 0x1f, 0x80, 0xfe, 99 | 0x3f, 0x80, 0x7e, 100 | 0x3f, 0x00, 0x7e, 101 | 0x3f, 0x00, 0x7e, 102 | 0x07, 0x00, 0x7e, 103 | 0x00, 0x00, 0x7e, 104 | 0x00, 0x00, 0x7e, 105 | 0x00, 0x00, 0xfe, 106 | 0x00, 0x00, 0xfc, 107 | 0x00, 0x01, 0xfc, 108 | 0x00, 0x03, 0xfc, 109 | 0x00, 0x03, 0xf8, 110 | 0x00, 0x07, 0xf8, 111 | 0x00, 0x0f, 0xf0, 112 | 0x00, 0x1f, 0xf0, 113 | 0x00, 0x3f, 0xe0, 114 | 0x00, 0x7f, 0xc0, 115 | 0x00, 0xff, 0x80, 116 | 0x01, 0xff, 0x00, 117 | 0x01, 0xfe, 0x00, 118 | 0x03, 0xfc, 0x00, 119 | 0x07, 0xfc, 0x00, 120 | 0x0f, 0xf8, 0x00, 121 | 0x0f, 0xf0, 0x00, 122 | 0x1f, 0xe0, 0x00, 123 | 0x1f, 0xc0, 0x00, 124 | 0x3f, 0xff, 0xfe, 125 | 0x3f, 0xff, 0xfe, 126 | 0x3f, 0xff, 0xfe, 127 | 0x7f, 0xff, 0xfe, 128 | 0x7f, 0xff, 0xfe, 129 | 0x7f, 0xff, 0xfe, 130 | 0x00, 0x00, 0x00, // 2 131 | 132 | 0x00, 0x7f, 0x00, 133 | 0x01, 0xff, 0xc0, 134 | 0x07, 0xff, 0xe0, 135 | 0x07, 0xff, 0xf0, 136 | 0x0f, 0xff, 0xf0, 137 | 0x1f, 0xff, 0xf8, 138 | 0x1f, 0xc3, 0xf8, 139 | 0x1f, 0x81, 0xfc, 140 | 0x3f, 0x80, 0xfc, 141 | 0x3f, 0x00, 0xfc, 142 | 0x07, 0x00, 0xfc, 143 | 0x00, 0x00, 0xfc, 144 | 0x00, 0x00, 0xfc, 145 | 0x00, 0x01, 0xf8, 146 | 0x00, 0x07, 0xf8, 147 | 0x00, 0x1f, 0xf0, 148 | 0x00, 0x1f, 0xe0, 149 | 0x00, 0x3f, 0xc0, 150 | 0x00, 0x3f, 0xe0, 151 | 0x00, 0x3f, 0xf0, 152 | 0x00, 0x3f, 0xf8, 153 | 0x00, 0x01, 0xfc, 154 | 0x00, 0x00, 0xfc, 155 | 0x00, 0x00, 0xfc, 156 | 0x00, 0x00, 0x7e, 157 | 0x00, 0x00, 0x7e, 158 | 0x00, 0x00, 0x7e, 159 | 0x00, 0x00, 0x7e, 160 | 0x07, 0x00, 0x7e, 161 | 0x3f, 0x00, 0x7e, 162 | 0x3f, 0x00, 0x7e, 163 | 0x3f, 0x80, 0xfc, 164 | 0x1f, 0xc1, 0xfc, 165 | 0x1f, 0xe3, 0xfc, 166 | 0x0f, 0xff, 0xf8, 167 | 0x0f, 0xff, 0xf8, 168 | 0x07, 0xff, 0xf0, 169 | 0x03, 0xff, 0xe0, 170 | 0x01, 0xff, 0x80, 171 | 0x00, 0x7e, 0x00, // 3 172 | 173 | 0x00, 0x01, 0xf0, 174 | 0x00, 0x03, 0xf0, 175 | 0x00, 0x07, 0xf0, 176 | 0x00, 0x07, 0xf0, 177 | 0x00, 0x0f, 0xf0, 178 | 0x00, 0x0f, 0xf0, 179 | 0x00, 0x1f, 0xf0, 180 | 0x00, 0x1f, 0xf0, 181 | 0x00, 0x3f, 0xf0, 182 | 0x00, 0x3f, 0xf0, 183 | 0x00, 0x7f, 0xf0, 184 | 0x00, 0xff, 0xf0, 185 | 0x00, 0xfb, 0xf0, 186 | 0x01, 0xfb, 0xf0, 187 | 0x01, 0xf3, 0xf0, 188 | 0x03, 0xf3, 0xf0, 189 | 0x03, 0xe3, 0xf0, 190 | 0x07, 0xe3, 0xf0, 191 | 0x07, 0xc3, 0xf0, 192 | 0x0f, 0xc3, 0xf0, 193 | 0x1f, 0x83, 0xf0, 194 | 0x1f, 0x83, 0xf0, 195 | 0x3f, 0x03, 0xf0, 196 | 0x3f, 0x03, 0xf0, 197 | 0x7e, 0x03, 0xf0, 198 | 0x7f, 0xff, 0xff, 199 | 0x7f, 0xff, 0xff, 200 | 0x7f, 0xff, 0xff, 201 | 0x7f, 0xff, 0xff, 202 | 0x7f, 0xff, 0xff, 203 | 0x7f, 0xff, 0xff, 204 | 0x00, 0x03, 0xf0, 205 | 0x00, 0x03, 0xf0, 206 | 0x00, 0x03, 0xf0, 207 | 0x00, 0x03, 0xf0, 208 | 0x00, 0x03, 0xf0, 209 | 0x00, 0x03, 0xf0, 210 | 0x00, 0x03, 0xf0, 211 | 0x00, 0x03, 0xf0, 212 | 0x00, 0x00, 0x00, // 4 213 | 214 | 0x00, 0x00, 0x00, 215 | 0x03, 0xff, 0xfe, 216 | 0x03, 0xff, 0xfe, 217 | 0x03, 0xff, 0xfe, 218 | 0x07, 0xff, 0xfe, 219 | 0x07, 0xff, 0xfe, 220 | 0x07, 0xff, 0xfe, 221 | 0x07, 0xe0, 0x00, 222 | 0x07, 0xe0, 0x00, 223 | 0x07, 0xe0, 0x00, 224 | 0x0f, 0xe0, 0x00, 225 | 0x0f, 0xc0, 0x00, 226 | 0x0f, 0xcf, 0x80, 227 | 0x0f, 0xdf, 0xe0, 228 | 0x0f, 0xff, 0xf0, 229 | 0x0f, 0xff, 0xf8, 230 | 0x0f, 0xff, 0xfc, 231 | 0x1f, 0xff, 0xfc, 232 | 0x1f, 0xe1, 0xfe, 233 | 0x1f, 0x80, 0xfe, 234 | 0x03, 0x80, 0x7e, 235 | 0x00, 0x00, 0x7f, 236 | 0x00, 0x00, 0x3f, 237 | 0x00, 0x00, 0x3f, 238 | 0x00, 0x00, 0x3f, 239 | 0x00, 0x00, 0x3f, 240 | 0x00, 0x00, 0x3f, 241 | 0x00, 0x00, 0x3f, 242 | 0x07, 0x00, 0x3f, 243 | 0x3f, 0x00, 0x3f, 244 | 0x3f, 0x80, 0x7e, 245 | 0x3f, 0x80, 0x7e, 246 | 0x1f, 0xc0, 0xfe, 247 | 0x1f, 0xe1, 0xfc, 248 | 0x0f, 0xff, 0xfc, 249 | 0x0f, 0xff, 0xf8, 250 | 0x07, 0xff, 0xf0, 251 | 0x03, 0xff, 0xe0, 252 | 0x01, 0xff, 0xc0, 253 | 0x00, 0x7f, 0x00, // 5 254 | 255 | 0x00, 0x3f, 0x00, 256 | 0x00, 0xff, 0xc0, 257 | 0x01, 0xff, 0xe0, 258 | 0x03, 0xff, 0xf0, 259 | 0x07, 0xff, 0xf8, 260 | 0x07, 0xff, 0xf8, 261 | 0x0f, 0xe3, 0xf8, 262 | 0x0f, 0xc1, 0xfc, 263 | 0x1f, 0x80, 0xfc, 264 | 0x1f, 0x80, 0xe0, 265 | 0x1f, 0x00, 0x00, 266 | 0x1f, 0x00, 0x00, 267 | 0x1f, 0x00, 0x00, 268 | 0x3f, 0x00, 0x00, 269 | 0x3f, 0x1f, 0x00, 270 | 0x3f, 0x7f, 0xc0, 271 | 0x3f, 0xff, 0xe0, 272 | 0x3f, 0xff, 0xf0, 273 | 0x3f, 0xff, 0xf8, 274 | 0x3f, 0xff, 0xf8, 275 | 0x3f, 0xe3, 0xfc, 276 | 0x3f, 0x80, 0xfc, 277 | 0x3f, 0x80, 0xfe, 278 | 0x3f, 0x00, 0x7e, 279 | 0x3f, 0x00, 0x7e, 280 | 0x3f, 0x00, 0x7e, 281 | 0x3f, 0x00, 0x7e, 282 | 0x3f, 0x00, 0x7e, 283 | 0x1f, 0x00, 0x7e, 284 | 0x1f, 0x00, 0x7e, 285 | 0x1f, 0x80, 0x7e, 286 | 0x1f, 0x80, 0xfc, 287 | 0x0f, 0xc0, 0xfc, 288 | 0x0f, 0xe1, 0xfc, 289 | 0x07, 0xff, 0xf8, 290 | 0x07, 0xff, 0xf8, 291 | 0x03, 0xff, 0xf0, 292 | 0x01, 0xff, 0xe0, 293 | 0x00, 0xff, 0xc0, 294 | 0x00, 0x3f, 0x00, // 6 295 | 296 | 297 | 0x00, 0x00, 0x00, 298 | 0x3f, 0xff, 0xfe, 299 | 0x3f, 0xff, 0xfe, 300 | 0x3f, 0xff, 0xfe, 301 | 0x3f, 0xff, 0xfe, 302 | 0x3f, 0xff, 0xfe, 303 | 0x3f, 0xff, 0xfe, 304 | 0x00, 0x00, 0xfc, 305 | 0x00, 0x01, 0xf8, 306 | 0x00, 0x03, 0xf8, 307 | 0x00, 0x03, 0xf0, 308 | 0x00, 0x07, 0xf0, 309 | 0x00, 0x07, 0xe0, 310 | 0x00, 0x0f, 0xc0, 311 | 0x00, 0x0f, 0xc0, 312 | 0x00, 0x1f, 0x80, 313 | 0x00, 0x1f, 0x80, 314 | 0x00, 0x3f, 0x80, 315 | 0x00, 0x3f, 0x00, 316 | 0x00, 0x3f, 0x00, 317 | 0x00, 0x7e, 0x00, 318 | 0x00, 0x7e, 0x00, 319 | 0x00, 0x7e, 0x00, 320 | 0x00, 0xfc, 0x00, 321 | 0x00, 0xfc, 0x00, 322 | 0x00, 0xfc, 0x00, 323 | 0x00, 0xfc, 0x00, 324 | 0x01, 0xf8, 0x00, 325 | 0x01, 0xf8, 0x00, 326 | 0x01, 0xf8, 0x00, 327 | 0x01, 0xf8, 0x00, 328 | 0x01, 0xf8, 0x00, 329 | 0x01, 0xf0, 0x00, 330 | 0x03, 0xf0, 0x00, 331 | 0x03, 0xf0, 0x00, 332 | 0x03, 0xf0, 0x00, 333 | 0x03, 0xf0, 0x00, 334 | 0x03, 0xf0, 0x00, 335 | 0x03, 0xf0, 0x00, 336 | 0x00, 0x00, 0x00, // 7 337 | 338 | 0x00, 0x7f, 0x00, 339 | 0x01, 0xff, 0xc0, 340 | 0x03, 0xff, 0xe0, 341 | 0x07, 0xff, 0xf0, 342 | 0x0f, 0xff, 0xf8, 343 | 0x0f, 0xff, 0xf8, 344 | 0x1f, 0xe3, 0xfc, 345 | 0x1f, 0xc1, 0xfc, 346 | 0x1f, 0x80, 0xfc, 347 | 0x1f, 0x80, 0xfc, 348 | 0x1f, 0x80, 0xfc, 349 | 0x1f, 0x80, 0xfc, 350 | 0x1f, 0x80, 0xfc, 351 | 0x0f, 0xc1, 0xf8, 352 | 0x0f, 0xe3, 0xf8, 353 | 0x07, 0xff, 0xf0, 354 | 0x03, 0xff, 0xe0, 355 | 0x01, 0xff, 0xc0, 356 | 0x03, 0xff, 0xe0, 357 | 0x07, 0xff, 0xf0, 358 | 0x0f, 0xff, 0xf8, 359 | 0x0f, 0xe3, 0xfc, 360 | 0x1f, 0x80, 0xfc, 361 | 0x1f, 0x80, 0xfc, 362 | 0x3f, 0x00, 0x7e, 363 | 0x3f, 0x00, 0x7e, 364 | 0x3f, 0x00, 0x7e, 365 | 0x3f, 0x00, 0x7e, 366 | 0x3f, 0x00, 0x7e, 367 | 0x3f, 0x00, 0x7e, 368 | 0x3f, 0x00, 0x7e, 369 | 0x3f, 0x80, 0xfe, 370 | 0x1f, 0xc0, 0xfc, 371 | 0x1f, 0xe3, 0xfc, 372 | 0x1f, 0xff, 0xfc, 373 | 0x0f, 0xff, 0xf8, 374 | 0x07, 0xff, 0xf0, 375 | 0x03, 0xff, 0xe0, 376 | 0x01, 0xff, 0xc0, 377 | 0x00, 0x7f, 0x00, // 8 378 | 379 | 0x00, 0xfe, 0x00, 380 | 0x03, 0xff, 0x80, 381 | 0x07, 0xff, 0xc0, 382 | 0x0f, 0xff, 0xe0, 383 | 0x1f, 0xff, 0xf0, 384 | 0x1f, 0xff, 0xf0, 385 | 0x3f, 0xc3, 0xf8, 386 | 0x3f, 0x01, 0xf8, 387 | 0x3f, 0x00, 0xfc, 388 | 0x7e, 0x00, 0xfc, 389 | 0x7e, 0x00, 0x7c, 390 | 0x7e, 0x00, 0x7c, 391 | 0x7e, 0x00, 0x7e, 392 | 0x7e, 0x00, 0x7e, 393 | 0x7e, 0x00, 0x7e, 394 | 0x7e, 0x00, 0x7e, 395 | 0x7e, 0x00, 0x7e, 396 | 0x7f, 0x00, 0xfe, 397 | 0x3f, 0x81, 0xfe, 398 | 0x3f, 0xc3, 0xfe, 399 | 0x1f, 0xff, 0xfe, 400 | 0x1f, 0xff, 0xfe, 401 | 0x0f, 0xff, 0xfe, 402 | 0x07, 0xff, 0xfe, 403 | 0x03, 0xff, 0x7e, 404 | 0x00, 0xfc, 0x7e, 405 | 0x00, 0x00, 0x7e, 406 | 0x00, 0x00, 0x7c, 407 | 0x00, 0x00, 0x7c, 408 | 0x00, 0x00, 0x7c, 409 | 0x07, 0x00, 0xfc, 410 | 0x3f, 0x00, 0xfc, 411 | 0x3f, 0x81, 0xf8, 412 | 0x1f, 0xc3, 0xf8, 413 | 0x1f, 0xff, 0xf0, 414 | 0x1f, 0xff, 0xf0, 415 | 0x0f, 0xff, 0xe0, 416 | 0x07, 0xff, 0xc0, 417 | 0x03, 0xff, 0x00, 418 | 0x00, 0xfc, 0x00 // 9 419 | }; 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_SSD1306/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for our Monochrome OLEDs based on SSD1306 drivers 3 | 4 | Pick one up today in the adafruit shop! 5 | ------> http://www.adafruit.com/category/63_98 6 | 7 | This example is for a 128x64 size display using I2C to communicate 8 | 3 pins are required to interface (2 I2C and one reset) 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. 15 | BSD license, check license.txt for more information 16 | All text above, and the splash screen must be included in any redistribution 17 | *********************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define OLED_RESET 4 25 | Adafruit_SSD1306 display(OLED_RESET); 26 | 27 | #define NUMFLAKES 10 28 | #define XPOS 0 29 | #define YPOS 1 30 | #define DELTAY 2 31 | 32 | 33 | #define LOGO16_GLCD_HEIGHT 16 34 | #define LOGO16_GLCD_WIDTH 16 35 | static const unsigned char PROGMEM logo16_glcd_bmp[] = 36 | { B00000000, B11000000, 37 | B00000001, B11000000, 38 | B00000001, B11000000, 39 | B00000011, B11100000, 40 | B11110011, B11100000, 41 | B11111110, B11111000, 42 | B01111110, B11111111, 43 | B00110011, B10011111, 44 | B00011111, B11111100, 45 | B00001101, B01110000, 46 | B00011011, B10100000, 47 | B00111111, B11100000, 48 | B00111111, B11110000, 49 | B01111100, B11110000, 50 | B01110000, B01110000, 51 | B00000000, B00110000 }; 52 | 53 | #if (SSD1306_LCDHEIGHT != 64) 54 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 55 | #endif 56 | 57 | void setup() { 58 | Serial.begin(9600); 59 | 60 | // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) 61 | display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64) 62 | // init done 63 | 64 | display.display(); // show splashscreen 65 | delay(2000); 66 | display.clearDisplay(); // clears the screen and buffer 67 | 68 | // draw a single pixel 69 | display.drawPixel(10, 10, WHITE); 70 | display.display(); 71 | delay(2000); 72 | display.clearDisplay(); 73 | 74 | // draw many lines 75 | testdrawline(); 76 | display.display(); 77 | delay(2000); 78 | display.clearDisplay(); 79 | 80 | // draw rectangles 81 | testdrawrect(); 82 | display.display(); 83 | delay(2000); 84 | display.clearDisplay(); 85 | 86 | // draw multiple rectangles 87 | testfillrect(); 88 | display.display(); 89 | delay(2000); 90 | display.clearDisplay(); 91 | 92 | // draw mulitple circles 93 | testdrawcircle(); 94 | display.display(); 95 | delay(2000); 96 | display.clearDisplay(); 97 | 98 | // draw a white circle, 10 pixel radius 99 | display.fillCircle(display.width()/2, display.height()/2, 10, WHITE); 100 | display.display(); 101 | delay(2000); 102 | display.clearDisplay(); 103 | 104 | testdrawroundrect(); 105 | delay(2000); 106 | display.clearDisplay(); 107 | 108 | testfillroundrect(); 109 | delay(2000); 110 | display.clearDisplay(); 111 | 112 | testdrawtriangle(); 113 | delay(2000); 114 | display.clearDisplay(); 115 | 116 | testfilltriangle(); 117 | delay(2000); 118 | display.clearDisplay(); 119 | 120 | // draw the first ~12 characters in the font 121 | testdrawchar(); 122 | display.display(); 123 | delay(2000); 124 | display.clearDisplay(); 125 | 126 | // draw scrolling text 127 | testscrolltext(); 128 | delay(2000); 129 | display.clearDisplay(); 130 | 131 | // text display tests 132 | display.setTextSize(1); 133 | display.setTextColor(WHITE); 134 | display.setCursor(0,0); 135 | display.println("Hello, world!"); 136 | display.setTextColor(BLACK, WHITE); // 'inverted' text 137 | display.println(3.141592); 138 | display.setTextSize(2); 139 | display.setTextColor(WHITE); 140 | display.print("0x"); display.println(0xDEADBEEF, HEX); 141 | display.display(); 142 | delay(2000); 143 | 144 | // miniature bitmap display 145 | display.clearDisplay(); 146 | display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1); 147 | display.display(); 148 | 149 | // invert the display 150 | display.invertDisplay(true); 151 | delay(1000); 152 | display.invertDisplay(false); 153 | delay(1000); 154 | 155 | // draw a bitmap icon and 'animate' movement 156 | testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH); 157 | } 158 | 159 | 160 | void loop() { 161 | 162 | } 163 | 164 | 165 | void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) { 166 | uint8_t icons[NUMFLAKES][3]; 167 | 168 | // initialize 169 | for (uint8_t f=0; f< NUMFLAKES; f++) { 170 | icons[f][XPOS] = random(display.width()); 171 | icons[f][YPOS] = 0; 172 | icons[f][DELTAY] = random(5) + 1; 173 | 174 | Serial.print("x: "); 175 | Serial.print(icons[f][XPOS], DEC); 176 | Serial.print(" y: "); 177 | Serial.print(icons[f][YPOS], DEC); 178 | Serial.print(" dy: "); 179 | Serial.println(icons[f][DELTAY], DEC); 180 | } 181 | 182 | while (1) { 183 | // draw each icon 184 | for (uint8_t f=0; f< NUMFLAKES; f++) { 185 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE); 186 | } 187 | display.display(); 188 | delay(200); 189 | 190 | // then erase it + move it 191 | for (uint8_t f=0; f< NUMFLAKES; f++) { 192 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK); 193 | // move it 194 | icons[f][YPOS] += icons[f][DELTAY]; 195 | // if its gone, reinit 196 | if (icons[f][YPOS] > display.height()) { 197 | icons[f][XPOS] = random(display.width()); 198 | icons[f][YPOS] = 0; 199 | icons[f][DELTAY] = random(5) + 1; 200 | } 201 | } 202 | } 203 | } 204 | 205 | 206 | void testdrawchar(void) { 207 | display.setTextSize(1); 208 | display.setTextColor(WHITE); 209 | display.setCursor(0,0); 210 | 211 | for (uint8_t i=0; i < 168; i++) { 212 | if (i == '\n') continue; 213 | display.write(i); 214 | if ((i > 0) && (i % 21 == 0)) 215 | display.println(); 216 | } 217 | display.display(); 218 | } 219 | 220 | void testdrawcircle(void) { 221 | for (int16_t i=0; i0; i-=5) { 249 | display.fillTriangle(display.width()/2, display.height()/2-i, 250 | display.width()/2-i, display.height()/2+i, 251 | display.width()/2+i, display.height()/2+i, WHITE); 252 | if (color == WHITE) color = BLACK; 253 | else color = WHITE; 254 | display.display(); 255 | } 256 | } 257 | 258 | void testdrawroundrect(void) { 259 | for (int16_t i=0; i=0; i-=4) { 299 | display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); 300 | display.display(); 301 | } 302 | delay(250); 303 | 304 | display.clearDisplay(); 305 | for (int16_t i=display.width()-1; i>=0; i-=4) { 306 | display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); 307 | display.display(); 308 | } 309 | for (int16_t i=display.height()-1; i>=0; i-=4) { 310 | display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); 311 | display.display(); 312 | } 313 | delay(250); 314 | 315 | display.clearDisplay(); 316 | for (int16_t i=0; i http://www.adafruit.com/category/63_98 6 | 7 | This example is for a 128x32 size display using I2C to communicate 8 | 3 pins are required to interface (2 I2C and one reset) 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. 15 | BSD license, check license.txt for more information 16 | All text above, and the splash screen must be included in any redistribution 17 | *********************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define OLED_RESET 4 25 | Adafruit_SSD1306 display(OLED_RESET); 26 | 27 | #define NUMFLAKES 10 28 | #define XPOS 0 29 | #define YPOS 1 30 | #define DELTAY 2 31 | 32 | 33 | #define LOGO16_GLCD_HEIGHT 16 34 | #define LOGO16_GLCD_WIDTH 16 35 | static const unsigned char PROGMEM logo16_glcd_bmp[] = 36 | { B00000000, B11000000, 37 | B00000001, B11000000, 38 | B00000001, B11000000, 39 | B00000011, B11100000, 40 | B11110011, B11100000, 41 | B11111110, B11111000, 42 | B01111110, B11111111, 43 | B00110011, B10011111, 44 | B00011111, B11111100, 45 | B00001101, B01110000, 46 | B00011011, B10100000, 47 | B00111111, B11100000, 48 | B00111111, B11110000, 49 | B01111100, B11110000, 50 | B01110000, B01110000, 51 | B00000000, B00110000 }; 52 | 53 | #if (SSD1306_LCDHEIGHT != 32) 54 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 55 | #endif 56 | 57 | void setup() { 58 | Serial.begin(9600); 59 | 60 | // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) 61 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32) 62 | // init done 63 | 64 | display.display(); // show splashscreen 65 | delay(2000); 66 | display.clearDisplay(); // clears the screen and buffer 67 | 68 | // draw a single pixel 69 | display.drawPixel(10, 10, WHITE); 70 | display.display(); 71 | delay(2000); 72 | display.clearDisplay(); 73 | 74 | // draw many lines 75 | testdrawline(); 76 | display.display(); 77 | delay(2000); 78 | display.clearDisplay(); 79 | 80 | // draw rectangles 81 | testdrawrect(); 82 | display.display(); 83 | delay(2000); 84 | display.clearDisplay(); 85 | 86 | // draw multiple rectangles 87 | testfillrect(); 88 | display.display(); 89 | delay(2000); 90 | display.clearDisplay(); 91 | 92 | // draw mulitple circles 93 | testdrawcircle(); 94 | display.display(); 95 | delay(2000); 96 | display.clearDisplay(); 97 | 98 | // draw a white circle, 10 pixel radius 99 | display.fillCircle(display.width()/2, display.height()/2, 10, WHITE); 100 | display.display(); 101 | delay(2000); 102 | display.clearDisplay(); 103 | 104 | testdrawroundrect(); 105 | delay(2000); 106 | display.clearDisplay(); 107 | 108 | testfillroundrect(); 109 | delay(2000); 110 | display.clearDisplay(); 111 | 112 | testdrawtriangle(); 113 | delay(2000); 114 | display.clearDisplay(); 115 | 116 | testfilltriangle(); 117 | delay(2000); 118 | display.clearDisplay(); 119 | 120 | // draw the first ~12 characters in the font 121 | testdrawchar(); 122 | display.display(); 123 | delay(2000); 124 | display.clearDisplay(); 125 | 126 | // draw scrolling text 127 | testscrolltext(); 128 | delay(2000); 129 | display.clearDisplay(); 130 | 131 | // text display tests 132 | display.setTextSize(1); 133 | display.setTextColor(WHITE); 134 | display.setCursor(0,0); 135 | display.println("Hello, world!"); 136 | display.setTextColor(BLACK, WHITE); // 'inverted' text 137 | display.println(3.141592); 138 | display.setTextSize(2); 139 | display.setTextColor(WHITE); 140 | display.print("0x"); display.println(0xDEADBEEF, HEX); 141 | display.display(); 142 | delay(2000); 143 | 144 | // miniature bitmap display 145 | display.clearDisplay(); 146 | display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1); 147 | display.display(); 148 | 149 | // invert the display 150 | display.invertDisplay(true); 151 | delay(1000); 152 | display.invertDisplay(false); 153 | delay(1000); 154 | 155 | // draw a bitmap icon and 'animate' movement 156 | testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH); 157 | } 158 | 159 | 160 | void loop() { 161 | 162 | } 163 | 164 | 165 | void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) { 166 | uint8_t icons[NUMFLAKES][3]; 167 | 168 | // initialize 169 | for (uint8_t f=0; f< NUMFLAKES; f++) { 170 | icons[f][XPOS] = random(display.width()); 171 | icons[f][YPOS] = 0; 172 | icons[f][DELTAY] = random(5) + 1; 173 | 174 | Serial.print("x: "); 175 | Serial.print(icons[f][XPOS], DEC); 176 | Serial.print(" y: "); 177 | Serial.print(icons[f][YPOS], DEC); 178 | Serial.print(" dy: "); 179 | Serial.println(icons[f][DELTAY], DEC); 180 | } 181 | 182 | while (1) { 183 | // draw each icon 184 | for (uint8_t f=0; f< NUMFLAKES; f++) { 185 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE); 186 | } 187 | display.display(); 188 | delay(200); 189 | 190 | // then erase it + move it 191 | for (uint8_t f=0; f< NUMFLAKES; f++) { 192 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK); 193 | // move it 194 | icons[f][YPOS] += icons[f][DELTAY]; 195 | // if its gone, reinit 196 | if (icons[f][YPOS] > display.height()) { 197 | icons[f][XPOS] = random(display.width()); 198 | icons[f][YPOS] = 0; 199 | icons[f][DELTAY] = random(5) + 1; 200 | } 201 | } 202 | } 203 | } 204 | 205 | 206 | void testdrawchar(void) { 207 | display.setTextSize(1); 208 | display.setTextColor(WHITE); 209 | display.setCursor(0,0); 210 | 211 | for (uint8_t i=0; i < 168; i++) { 212 | if (i == '\n') continue; 213 | display.write(i); 214 | if ((i > 0) && (i % 21 == 0)) 215 | display.println(); 216 | } 217 | display.display(); 218 | } 219 | 220 | void testdrawcircle(void) { 221 | for (int16_t i=0; i0; i-=5) { 249 | display.fillTriangle(display.width()/2, display.height()/2-i, 250 | display.width()/2-i, display.height()/2+i, 251 | display.width()/2+i, display.height()/2+i, WHITE); 252 | if (color == WHITE) color = BLACK; 253 | else color = WHITE; 254 | display.display(); 255 | } 256 | } 257 | 258 | void testdrawroundrect(void) { 259 | for (int16_t i=0; i=0; i-=4) { 299 | display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); 300 | display.display(); 301 | } 302 | delay(250); 303 | 304 | display.clearDisplay(); 305 | for (int16_t i=display.width()-1; i>=0; i-=4) { 306 | display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); 307 | display.display(); 308 | } 309 | for (int16_t i=display.height()-1; i>=0; i-=4) { 310 | display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); 311 | display.display(); 312 | } 313 | delay(250); 314 | 315 | display.clearDisplay(); 316 | for (int16_t i=0; i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "EEPROMAnything.h" 9 | 10 | // If using software SPI (the default case): 11 | #define OLED_MOSI 9 12 | #define OLED_CLK 10 13 | #define OLED_DC 11 14 | #define OLED_CS 12 15 | #define OLED_RESET 13 16 | 17 | #define BUTTON1_PIN 4 18 | 19 | #define HPA 0 20 | #define METER 1 21 | #define DEG 2 22 | #define MVOLT 3 23 | 24 | Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 25 | 26 | /* Uncomment this block to use hardware SPI 27 | #define OLED_DC 6 28 | #define OLED_CS 7 29 | #define OLED_RESET 8 30 | Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); 31 | */ 32 | 33 | extern uint8_t Font24x40[]; 34 | extern uint8_t Symbol[]; 35 | extern uint8_t Splash[]; 36 | extern uint8_t Battery[]; 37 | 38 | SFE_BMP180 pressure; 39 | Button button1 = Button(BUTTON1_PIN,BUTTON_PULLDOWN); 40 | boolean longPush = false; 41 | int value, etat = 0; 42 | double QNH, saveQNH; 43 | double temperature, pression, altitude = 0; 44 | double baseAltitude, saveBaseAltitude = 0; 45 | double altiMin = 9999.0; 46 | double altiMax = 0.0; 47 | double lastValue = 0.0; 48 | long lastVcc, vcc = 0; 49 | int eepromAddr = 10; 50 | 51 | #define MAX_SAMPLES 20 52 | double samplesBuffer[MAX_SAMPLES]; 53 | int indexBfr = 0; 54 | double averagePressure = 0; 55 | boolean bufferReady = false; 56 | int screen = 0; // numero d'ecran 57 | #define NB_SCREENS 6 58 | String debugMsg; 59 | 60 | /* ------------------------------------ setup ------------------------------------------ */ 61 | void setup() { 62 | button1.releaseHandler(handleButtonReleaseEvents); 63 | button1.holdHandler(handleButtonHoldEvents,2000); 64 | 65 | display.begin(SSD1306_SWITCHCAPVCC); 66 | 67 | // init QNH 68 | EEPROM_readAnything(eepromAddr, QNH); 69 | if (isnan(QNH)) { 70 | QNH = 1013.25; 71 | EEPROM_writeAnything(eepromAddr, QNH); // QNH standard 72 | } 73 | saveQNH = QNH; 74 | 75 | display.clearDisplay(); 76 | display.drawBitmap(0, 0, Splash, 128, 64, 1); 77 | display.display(); 78 | delay(1000); 79 | display.clearDisplay(); 80 | display.setTextSize(1); 81 | display.setTextColor(WHITE); 82 | display.setCursor(0,0); 83 | if (!pressure.begin()) { 84 | display.println("Init fail !"); 85 | display.println("Turn OFF"); 86 | display.display(); 87 | while(1); // Pause forever. 88 | } 89 | 90 | button1.isPressed(); 91 | screen = 1; 92 | } 93 | 94 | /* ------------------------------------ loop ------------------------------------------ */ 95 | void loop() { 96 | char status; 97 | long vcc; 98 | 99 | button1.isPressed(); 100 | 101 | // get pressure and temperature and calculate altitude 102 | status = pressure.startTemperature(); 103 | if (status != 0) { 104 | delay(status); 105 | status = pressure.getTemperature(temperature); 106 | if (status != 0) { 107 | status = pressure.startPressure(0); 108 | if (status != 0) { 109 | delay(status); 110 | status = pressure.getPressure(pression, temperature); 111 | if (status != 0) { 112 | savePressureSample(pression); 113 | averagePressure = getPressureAverage(); 114 | if (bufferReady) { 115 | altitude = pressure.altitude(averagePressure*100, QNH*100); 116 | setAltiMinMax(); 117 | } 118 | 119 | } 120 | } 121 | } 122 | } 123 | 124 | if (etat == 0) { 125 | // init baseAltitude 126 | if (baseAltitude == 0) { 127 | baseAltitude = round(altitude); 128 | saveBaseAltitude = baseAltitude; 129 | } 130 | // calculate QNH 131 | if (baseAltitude != saveBaseAltitude) { 132 | QNH = pressure.sealevel(pression, baseAltitude); 133 | saveBaseAltitude = baseAltitude; 134 | } 135 | // Save QNH in EEPROM 136 | if (QNH != saveQNH) { 137 | saveQNH = QNH; 138 | EEPROM_writeAnything(eepromAddr, QNH); 139 | } 140 | 141 | switch (screen) { 142 | case 1: // Altitude 143 | if (lastValue != altitude) { 144 | showScreen("ALTITUDE", altitude, METER); 145 | lastValue = altitude; 146 | } 147 | break; 148 | 149 | case 2: // Altitude Max 150 | if (lastValue != altiMax) { 151 | showScreen("ALTITUDE MAX", altiMax, METER); 152 | lastValue = altiMax; 153 | } 154 | break; 155 | 156 | case 3: // Altitude Min 157 | if (lastValue != altiMin) { 158 | showScreen("ALTITUDE MIN", altiMin, METER); 159 | lastValue = altiMin; 160 | } 161 | break; 162 | 163 | case 4: // Pression 164 | if (lastValue != pression) { 165 | showScreen("PRESSION", pression, HPA); 166 | lastValue = pression; 167 | } 168 | break; 169 | 170 | case 5: // Temperature 171 | if (lastValue != temperature) { 172 | showScreen("TEMPERATURE", temperature, DEG); 173 | lastValue = temperature; 174 | } 175 | break; 176 | 177 | case 6: // Batterie 178 | vcc = readVcc(); 179 | if (lastVcc != vcc) { 180 | showScreen("BATTERIE", vcc, MVOLT); 181 | lastVcc = vcc; 182 | } 183 | break; 184 | } 185 | } 186 | else { // Settings 187 | // Settings 188 | display.clearDisplay(); 189 | display.setTextSize(1); 190 | display.setCursor(0,0); 191 | display.println("CALIBRATION"); 192 | display.setCursor(0,15); 193 | display.print("QNH : "); 194 | display.print(QNH,2); 195 | display.println(" hPa"); 196 | //display.print("Debug : "); 197 | //display.println(debugMsg); 198 | //display.print("Etat : "); 199 | //display.println(etat); 200 | if (etat == 1) drawSymbol(100, 40, 4); //UP 201 | if (etat == 2) drawSymbol(100, 40, 5); // DOWN 202 | if (value != 0) { 203 | baseAltitude += value; 204 | value = 0; 205 | // recalcule le QNH 206 | QNH = pressure.sealevel(pression, baseAltitude); 207 | } 208 | display.setCursor(0,45); 209 | display.print("Alti : "); 210 | display.println(baseAltitude, 0); 211 | display.display(); 212 | } 213 | 214 | delay(50); 215 | } 216 | /* -------------------- fonctions -------------------- */ 217 | 218 | // Affiche les données d'un ecran 219 | void showScreen(String label, double value, int unit) { 220 | display.clearDisplay(); 221 | showBatterylevel(readVcc()); 222 | display.setCursor(0,0); 223 | display.println(label); 224 | drawFloatValue(0, 20, value, unit); 225 | display.display(); 226 | } 227 | 228 | // Enregistre un echantillon de pression 229 | void savePressureSample(float pressure) { 230 | if (indexBfr == MAX_SAMPLES) { 231 | indexBfr = 0; 232 | bufferReady = true; 233 | } 234 | samplesBuffer[indexBfr++] = pressure; 235 | } 236 | 237 | // Retourne la moyenne des echantillons de pression 238 | float getPressureAverage() { 239 | double sum = 0; 240 | for (int i =0; i altiMax) altiMax = altitude; 249 | if (altitude < altiMin) altiMin = altitude; 250 | } 251 | void resetAltiMinMax() { 252 | altiMax = altiMin = altitude; 253 | } 254 | // Gestion du bouton relaché 255 | void handleButtonReleaseEvents(Button &btn) { 256 | //debugMsg = "Release"; 257 | if (!longPush) { 258 | if (etat != 0 ) { // Settings 259 | if (etat == 1) value = 1; 260 | if (etat == 2) value = -1; 261 | } 262 | else { // Change screen 263 | screen++; 264 | if (screen > NB_SCREENS) screen = 1; 265 | lastValue = 0; 266 | } 267 | } 268 | longPush = false; 269 | } 270 | 271 | // Gestion de l'appui prolongé sur le bouton 272 | void handleButtonHoldEvents(Button &btn) { 273 | //debugMsg = "Hold"; 274 | longPush = true; 275 | //screen = 1; 276 | value = 0; 277 | if (screen == 1 && ++etat > 2) { 278 | etat = 0; 279 | } 280 | else if (screen == 2 || screen == 3) { 281 | resetAltiMinMax(); 282 | } 283 | } 284 | 285 | // Affiche un caractére en x, y 286 | void drawCar(int sx, int sy, int num, uint8_t *font, int fw, int fh, int color) { 287 | byte row; 288 | for(int y=0; y 5) { // pas de decimal 319 | for (int n=0; n<4; n++) drawBigCar(sx+n*26, sy, charBuf[n]- '0'); 320 | drawSymbol(108,sy, unit); 321 | } 322 | else { 323 | drawBigCar(sx+86, sy, charBuf[nbCar-1]- '0'); 324 | drawDot(78, sy+39, 6); 325 | nbCar--; 326 | if (--nbCar > 0) drawBigCar(sx+52, sy, charBuf[nbCar-1]- '0'); 327 | if (--nbCar > 0) drawBigCar(sx+26, sy, charBuf[nbCar-1]- '0'); 328 | if (--nbCar > 0) drawBigCar(sx, sy, charBuf[nbCar-1]- '0'); 329 | drawSymbol(112,sy, unit); 330 | } 331 | } 332 | } 333 | // Show battery level icon 334 | void showBatterylevel(long vcc) { 335 | if (vcc > 3600) display.drawBitmap(104, 1, Battery, 20, 7, 1); 336 | else if (vcc > 3400) display.drawBitmap(104, 1, Battery+21, 20, 7, 1); 337 | else if (vcc > 3200) display.drawBitmap(104, 1, Battery+42, 20, 7, 1); 338 | else if (vcc > 3000) display.drawBitmap(104, 1, Battery+63, 20, 7, 1); 339 | else display.drawBitmap(104, 1, Battery+84, 20, 7, 1); 340 | } 341 | // Read VCC 342 | long readVcc() { 343 | long result; 344 | // Read 1.1V reference against AVcc 345 | ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 346 | delay(2); // Wait for Vref to settle 347 | ADCSRA |= _BV(ADSC); // Convert 348 | while (bit_is_set(ADCSRA,ADSC)); 349 | result = ADCL; 350 | result |= ADCH<<8; 351 | result = 1126400L / result; // Back-calculate AVcc in mV 352 | return result; 353 | } 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_SSD1306/examples/ssd1306_128x32_spi/ssd1306_128x32_spi.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for our Monochrome OLEDs based on SSD1306 drivers 3 | 4 | Pick one up today in the adafruit shop! 5 | ------> http://www.adafruit.com/category/63_98 6 | 7 | This example is for a 128x32 size display using SPI to communicate 8 | 4 or 5 pins are required to interface 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. 15 | BSD license, check license.txt for more information 16 | All text above, and the splash screen must be included in any redistribution 17 | *********************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // If using software SPI (the default case): 25 | #define OLED_MOSI 9 26 | #define OLED_CLK 10 27 | #define OLED_DC 11 28 | #define OLED_CS 12 29 | #define OLED_RESET 13 30 | Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 31 | 32 | /* Uncomment this block to use hardware SPI 33 | #define OLED_DC 6 34 | #define OLED_CS 7 35 | #define OLED_RESET 8 36 | Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); 37 | */ 38 | 39 | #define NUMFLAKES 10 40 | #define XPOS 0 41 | #define YPOS 1 42 | #define DELTAY 2 43 | 44 | #define LOGO16_GLCD_HEIGHT 16 45 | #define LOGO16_GLCD_WIDTH 16 46 | static const unsigned char PROGMEM logo16_glcd_bmp[] = 47 | { B00000000, B11000000, 48 | B00000001, B11000000, 49 | B00000001, B11000000, 50 | B00000011, B11100000, 51 | B11110011, B11100000, 52 | B11111110, B11111000, 53 | B01111110, B11111111, 54 | B00110011, B10011111, 55 | B00011111, B11111100, 56 | B00001101, B01110000, 57 | B00011011, B10100000, 58 | B00111111, B11100000, 59 | B00111111, B11110000, 60 | B01111100, B11110000, 61 | B01110000, B01110000, 62 | B00000000, B00110000 }; 63 | 64 | #if (SSD1306_LCDHEIGHT != 32) 65 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 66 | #endif 67 | 68 | void setup() { 69 | Serial.begin(9600); 70 | 71 | // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) 72 | display.begin(SSD1306_SWITCHCAPVCC); 73 | // init done 74 | 75 | display.display(); // show splashscreen 76 | delay(2000); 77 | display.clearDisplay(); // clears the screen and buffer 78 | 79 | // draw a single pixel 80 | display.drawPixel(10, 10, WHITE); 81 | display.display(); 82 | delay(2000); 83 | display.clearDisplay(); 84 | 85 | // draw many lines 86 | testdrawline(); 87 | display.display(); 88 | delay(2000); 89 | display.clearDisplay(); 90 | 91 | // draw rectangles 92 | testdrawrect(); 93 | display.display(); 94 | delay(2000); 95 | display.clearDisplay(); 96 | 97 | // draw multiple rectangles 98 | testfillrect(); 99 | display.display(); 100 | delay(2000); 101 | display.clearDisplay(); 102 | 103 | // draw mulitple circles 104 | testdrawcircle(); 105 | display.display(); 106 | delay(2000); 107 | display.clearDisplay(); 108 | 109 | // draw a white circle, 10 pixel radius 110 | display.fillCircle(display.width()/2, display.height()/2, 10, WHITE); 111 | display.display(); 112 | delay(2000); 113 | display.clearDisplay(); 114 | 115 | testdrawroundrect(); 116 | delay(2000); 117 | display.clearDisplay(); 118 | 119 | testfillroundrect(); 120 | delay(2000); 121 | display.clearDisplay(); 122 | 123 | testdrawtriangle(); 124 | delay(2000); 125 | display.clearDisplay(); 126 | 127 | testfilltriangle(); 128 | delay(2000); 129 | display.clearDisplay(); 130 | 131 | // draw the first ~12 characters in the font 132 | testdrawchar(); 133 | display.display(); 134 | delay(2000); 135 | display.clearDisplay(); 136 | 137 | // draw scrolling text 138 | testscrolltext(); 139 | delay(2000); 140 | display.clearDisplay(); 141 | 142 | // text display tests 143 | display.setTextSize(1); 144 | display.setTextColor(WHITE); 145 | display.setCursor(0,0); 146 | display.println("Hello, world!"); 147 | display.setTextColor(BLACK, WHITE); // 'inverted' text 148 | display.println(3.141592); 149 | display.setTextSize(2); 150 | display.setTextColor(WHITE); 151 | display.print("0x"); display.println(0xDEADBEEF, HEX); 152 | display.display(); 153 | delay(2000); 154 | 155 | // miniature bitmap display 156 | display.clearDisplay(); 157 | display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1); 158 | display.display(); 159 | 160 | // invert the display 161 | display.invertDisplay(true); 162 | delay(1000); 163 | display.invertDisplay(false); 164 | delay(1000); 165 | 166 | // draw a bitmap icon and 'animate' movement 167 | testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH); 168 | } 169 | 170 | 171 | void loop() { 172 | 173 | } 174 | 175 | 176 | void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) { 177 | uint8_t icons[NUMFLAKES][3]; 178 | 179 | // initialize 180 | for (uint8_t f=0; f< NUMFLAKES; f++) { 181 | icons[f][XPOS] = random(display.width()); 182 | icons[f][YPOS] = 0; 183 | icons[f][DELTAY] = random(5) + 1; 184 | 185 | Serial.print("x: "); 186 | Serial.print(icons[f][XPOS], DEC); 187 | Serial.print(" y: "); 188 | Serial.print(icons[f][YPOS], DEC); 189 | Serial.print(" dy: "); 190 | Serial.println(icons[f][DELTAY], DEC); 191 | } 192 | 193 | while (1) { 194 | // draw each icon 195 | for (uint8_t f=0; f< NUMFLAKES; f++) { 196 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE); 197 | } 198 | display.display(); 199 | delay(200); 200 | 201 | // then erase it + move it 202 | for (uint8_t f=0; f< NUMFLAKES; f++) { 203 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK); 204 | // move it 205 | icons[f][YPOS] += icons[f][DELTAY]; 206 | // if its gone, reinit 207 | if (icons[f][YPOS] > display.height()) { 208 | icons[f][XPOS] = random(display.width()); 209 | icons[f][YPOS] = 0; 210 | icons[f][DELTAY] = random(5) + 1; 211 | } 212 | } 213 | } 214 | } 215 | 216 | 217 | void testdrawchar(void) { 218 | display.setTextSize(1); 219 | display.setTextColor(WHITE); 220 | display.setCursor(0,0); 221 | 222 | for (uint8_t i=0; i < 168; i++) { 223 | if (i == '\n') continue; 224 | display.write(i); 225 | if ((i > 0) && (i % 21 == 0)) 226 | display.println(); 227 | } 228 | display.display(); 229 | } 230 | 231 | void testdrawcircle(void) { 232 | for (int16_t i=0; i0; i-=5) { 260 | display.fillTriangle(display.width()/2, display.height()/2-i, 261 | display.width()/2-i, display.height()/2+i, 262 | display.width()/2+i, display.height()/2+i, WHITE); 263 | if (color == WHITE) color = BLACK; 264 | else color = WHITE; 265 | display.display(); 266 | } 267 | } 268 | 269 | void testdrawroundrect(void) { 270 | for (int16_t i=0; i=0; i-=4) { 310 | display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); 311 | display.display(); 312 | } 313 | delay(250); 314 | 315 | display.clearDisplay(); 316 | for (int16_t i=display.width()-1; i>=0; i-=4) { 317 | display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); 318 | display.display(); 319 | } 320 | for (int16_t i=display.height()-1; i>=0; i-=4) { 321 | display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); 322 | display.display(); 323 | } 324 | delay(250); 325 | 326 | display.clearDisplay(); 327 | for (int16_t i=0; i http://www.adafruit.com/category/63_98 6 | 7 | This example is for a 128x64 size display using SPI to communicate 8 | 4 or 5 pins are required to interface 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. 15 | BSD license, check license.txt for more information 16 | All text above, and the splash screen must be included in any redistribution 17 | *********************************************************************/ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // If using software SPI (the default case): 25 | #define OLED_MOSI 9 26 | #define OLED_CLK 10 27 | #define OLED_DC 11 28 | #define OLED_CS 12 29 | #define OLED_RESET 13 30 | Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 31 | 32 | /* Uncomment this block to use hardware SPI 33 | #define OLED_DC 6 34 | #define OLED_CS 7 35 | #define OLED_RESET 8 36 | Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); 37 | */ 38 | 39 | #define NUMFLAKES 10 40 | #define XPOS 0 41 | #define YPOS 1 42 | #define DELTAY 2 43 | 44 | #define LOGO16_GLCD_HEIGHT 16 45 | #define LOGO16_GLCD_WIDTH 16 46 | static const unsigned char PROGMEM logo16_glcd_bmp[] = 47 | { B00000000, B11000000, 48 | B00000001, B11000000, 49 | B00000001, B11000000, 50 | B00000011, B11100000, 51 | B11110011, B11100000, 52 | B11111110, B11111000, 53 | B01111110, B11111111, 54 | B00110011, B10011111, 55 | B00011111, B11111100, 56 | B00001101, B01110000, 57 | B00011011, B10100000, 58 | B00111111, B11100000, 59 | B00111111, B11110000, 60 | B01111100, B11110000, 61 | B01110000, B01110000, 62 | B00000000, B00110000 }; 63 | 64 | #if (SSD1306_LCDHEIGHT != 64) 65 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 66 | #endif 67 | 68 | void setup() { 69 | Serial.begin(9600); 70 | 71 | // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) 72 | display.begin(SSD1306_SWITCHCAPVCC); 73 | // init done 74 | 75 | display.display(); // show splashscreen 76 | delay(2000); 77 | display.clearDisplay(); // clears the screen and buffer 78 | 79 | // draw a single pixel 80 | display.drawPixel(10, 10, WHITE); 81 | display.display(); 82 | delay(2000); 83 | display.clearDisplay(); 84 | 85 | // draw many lines 86 | testdrawline(); 87 | display.display(); 88 | delay(2000); 89 | display.clearDisplay(); 90 | 91 | // draw rectangles 92 | testdrawrect(); 93 | display.display(); 94 | delay(2000); 95 | display.clearDisplay(); 96 | 97 | // draw multiple rectangles 98 | testfillrect(); 99 | display.display(); 100 | delay(2000); 101 | display.clearDisplay(); 102 | 103 | // draw mulitple circles 104 | testdrawcircle(); 105 | display.display(); 106 | delay(2000); 107 | display.clearDisplay(); 108 | 109 | // draw a white circle, 10 pixel radius 110 | display.fillCircle(display.width()/2, display.height()/2, 10, WHITE); 111 | display.display(); 112 | delay(2000); 113 | display.clearDisplay(); 114 | 115 | testdrawroundrect(); 116 | delay(2000); 117 | display.clearDisplay(); 118 | 119 | testfillroundrect(); 120 | delay(2000); 121 | display.clearDisplay(); 122 | 123 | testdrawtriangle(); 124 | delay(2000); 125 | display.clearDisplay(); 126 | 127 | testfilltriangle(); 128 | delay(2000); 129 | display.clearDisplay(); 130 | 131 | // draw the first ~12 characters in the font 132 | testdrawchar(); 133 | display.display(); 134 | delay(2000); 135 | display.clearDisplay(); 136 | 137 | // draw scrolling text 138 | testscrolltext(); 139 | delay(2000); 140 | display.clearDisplay(); 141 | 142 | // text display tests 143 | display.setTextSize(1); 144 | display.setTextColor(WHITE); 145 | display.setCursor(0,0); 146 | display.println("Hello, world!"); 147 | display.setTextColor(BLACK, WHITE); // 'inverted' text 148 | display.println(3.141592); 149 | display.setTextSize(2); 150 | display.setTextColor(WHITE); 151 | display.print("0x"); display.println(0xDEADBEEF, HEX); 152 | display.display(); 153 | delay(2000); 154 | 155 | // miniature bitmap display 156 | display.clearDisplay(); 157 | display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1); 158 | display.display(); 159 | 160 | // invert the display 161 | display.invertDisplay(true); 162 | delay(1000); 163 | display.invertDisplay(false); 164 | delay(1000); 165 | 166 | // draw a bitmap icon and 'animate' movement 167 | testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH); 168 | } 169 | 170 | 171 | void loop() { 172 | 173 | } 174 | 175 | 176 | void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) { 177 | uint8_t icons[NUMFLAKES][3]; 178 | 179 | // initialize 180 | for (uint8_t f=0; f< NUMFLAKES; f++) { 181 | icons[f][XPOS] = random(display.width()); 182 | icons[f][YPOS] = 0; 183 | icons[f][DELTAY] = random(5) + 1; 184 | 185 | Serial.print("x: "); 186 | Serial.print(icons[f][XPOS], DEC); 187 | Serial.print(" y: "); 188 | Serial.print(icons[f][YPOS], DEC); 189 | Serial.print(" dy: "); 190 | Serial.println(icons[f][DELTAY], DEC); 191 | } 192 | 193 | while (1) { 194 | // draw each icon 195 | for (uint8_t f=0; f< NUMFLAKES; f++) { 196 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE); 197 | } 198 | display.display(); 199 | delay(200); 200 | 201 | // then erase it + move it 202 | for (uint8_t f=0; f< NUMFLAKES; f++) { 203 | display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, BLACK); 204 | // move it 205 | icons[f][YPOS] += icons[f][DELTAY]; 206 | // if its gone, reinit 207 | if (icons[f][YPOS] > display.height()) { 208 | icons[f][XPOS] = random(display.width()); 209 | icons[f][YPOS] = 0; 210 | icons[f][DELTAY] = random(5) + 1; 211 | } 212 | } 213 | } 214 | } 215 | 216 | 217 | void testdrawchar(void) { 218 | display.setTextSize(1); 219 | display.setTextColor(WHITE); 220 | display.setCursor(0,0); 221 | 222 | for (uint8_t i=0; i < 168; i++) { 223 | if (i == '\n') continue; 224 | display.write(i); 225 | if ((i > 0) && (i % 21 == 0)) 226 | display.println(); 227 | } 228 | display.display(); 229 | } 230 | 231 | void testdrawcircle(void) { 232 | for (int16_t i=0; i0; i-=5) { 260 | display.fillTriangle(display.width()/2, display.height()/2-i, 261 | display.width()/2-i, display.height()/2+i, 262 | display.width()/2+i, display.height()/2+i, WHITE); 263 | if (color == WHITE) color = BLACK; 264 | else color = WHITE; 265 | display.display(); 266 | } 267 | } 268 | 269 | void testdrawroundrect(void) { 270 | for (int16_t i=0; i=0; i-=4) { 310 | display.drawLine(0, display.height()-1, display.width()-1, i, WHITE); 311 | display.display(); 312 | } 313 | delay(250); 314 | 315 | display.clearDisplay(); 316 | for (int16_t i=display.width()-1; i>=0; i-=4) { 317 | display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE); 318 | display.display(); 319 | } 320 | for (int16_t i=display.height()-1; i>=0; i-=4) { 321 | display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE); 322 | display.display(); 323 | } 324 | delay(250); 325 | 326 | display.clearDisplay(); 327 | for (int16_t i=0; i 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | SFE_BMP180::SFE_BMP180() 26 | // Base library type 27 | { 28 | } 29 | 30 | 31 | char SFE_BMP180::begin() 32 | // Initialize library for subsequent pressure measurements 33 | { 34 | double c3,c4,b1; 35 | 36 | // Start up the Arduino's "wire" (I2C) library: 37 | 38 | Wire.begin(); 39 | 40 | // The BMP180 includes factory calibration data stored on the device. 41 | // Each device has different numbers, these must be retrieved and 42 | // used in the calculations when taking pressure measurements. 43 | 44 | // Retrieve calibration data from device: 45 | 46 | if (readInt(0xAA,AC1) && 47 | readInt(0xAC,AC2) && 48 | readInt(0xAE,AC3) && 49 | readUInt(0xB0,AC4) && 50 | readUInt(0xB2,AC5) && 51 | readUInt(0xB4,AC6) && 52 | readInt(0xB6,VB1) && 53 | readInt(0xB8,VB2) && 54 | readInt(0xBA,MB) && 55 | readInt(0xBC,MC) && 56 | readInt(0xBE,MD)) 57 | { 58 | 59 | // All reads completed successfully! 60 | 61 | // If you need to check your math using known numbers, 62 | // you can uncomment one of these examples. 63 | // (The correct results are commented in the below functions.) 64 | 65 | // Example from Bosch datasheet 66 | // AC1 = 408; AC2 = -72; AC3 = -14383; AC4 = 32741; AC5 = 32757; AC6 = 23153; 67 | // B1 = 6190; B2 = 4; MB = -32768; MC = -8711; MD = 2868; 68 | 69 | // Example from http://wmrx00.sourceforge.net/Arduino/BMP180-Calcs.pdf 70 | // AC1 = 7911; AC2 = -934; AC3 = -14306; AC4 = 31567; AC5 = 25671; AC6 = 18974; 71 | // VB1 = 5498; VB2 = 46; MB = -32768; MC = -11075; MD = 2432; 72 | 73 | /* 74 | Serial.print("AC1: "); Serial.println(AC1); 75 | Serial.print("AC2: "); Serial.println(AC2); 76 | Serial.print("AC3: "); Serial.println(AC3); 77 | Serial.print("AC4: "); Serial.println(AC4); 78 | Serial.print("AC5: "); Serial.println(AC5); 79 | Serial.print("AC6: "); Serial.println(AC6); 80 | Serial.print("VB1: "); Serial.println(VB1); 81 | Serial.print("VB2: "); Serial.println(VB2); 82 | Serial.print("MB: "); Serial.println(MB); 83 | Serial.print("MC: "); Serial.println(MC); 84 | Serial.print("MD: "); Serial.println(MD); 85 | */ 86 | 87 | // Compute floating-point polynominals: 88 | 89 | c3 = 160.0 * pow(2,-15) * AC3; 90 | c4 = pow(10,-3) * pow(2,-15) * AC4; 91 | b1 = pow(160,2) * pow(2,-30) * VB1; 92 | c5 = (pow(2,-15) / 160) * AC5; 93 | c6 = AC6; 94 | mc = (pow(2,11) / pow(160,2)) * MC; 95 | md = MD / 160.0; 96 | x0 = AC1; 97 | x1 = 160.0 * pow(2,-13) * AC2; 98 | x2 = pow(160,2) * pow(2,-25) * VB2; 99 | y0 = c4 * pow(2,15); 100 | y1 = c4 * c3; 101 | y2 = c4 * b1; 102 | p0 = (3791.0 - 8.0) / 1600.0; 103 | p1 = 1.0 - 7357.0 * pow(2,-20); 104 | p2 = 3038.0 * 100.0 * pow(2,-36); 105 | 106 | /* 107 | Serial.println(); 108 | Serial.print("c3: "); Serial.println(c3); 109 | Serial.print("c4: "); Serial.println(c4); 110 | Serial.print("c5: "); Serial.println(c5); 111 | Serial.print("c6: "); Serial.println(c6); 112 | Serial.print("b1: "); Serial.println(b1); 113 | Serial.print("mc: "); Serial.println(mc); 114 | Serial.print("md: "); Serial.println(md); 115 | Serial.print("x0: "); Serial.println(x0); 116 | Serial.print("x1: "); Serial.println(x1); 117 | Serial.print("x2: "); Serial.println(x2); 118 | Serial.print("y0: "); Serial.println(y0); 119 | Serial.print("y1: "); Serial.println(y1); 120 | Serial.print("y2: "); Serial.println(y2); 121 | Serial.print("p0: "); Serial.println(p0); 122 | Serial.print("p1: "); Serial.println(p1); 123 | Serial.print("p2: "); Serial.println(p2); 124 | */ 125 | 126 | // Success! 127 | return(1); 128 | } 129 | else 130 | { 131 | // Error reading calibration data; bad component or connection? 132 | return(0); 133 | } 134 | } 135 | 136 | 137 | char SFE_BMP180::readInt(char address, int &value) 138 | // Read a signed integer (two bytes) from device 139 | // address: register to start reading (plus subsequent register) 140 | // value: external variable to store data (function modifies value) 141 | { 142 | unsigned char data[2]; 143 | 144 | data[0] = address; 145 | if (readBytes(data,2)) 146 | { 147 | value = (((int)data[0]<<8)|(int)data[1]); 148 | //if (*value & 0x8000) *value |= 0xFFFF0000; // sign extend if negative 149 | return(1); 150 | } 151 | value = 0; 152 | return(0); 153 | } 154 | 155 | 156 | char SFE_BMP180::readUInt(char address, unsigned int &value) 157 | // Read an unsigned integer (two bytes) from device 158 | // address: register to start reading (plus subsequent register) 159 | // value: external variable to store data (function modifies value) 160 | { 161 | unsigned char data[2]; 162 | 163 | data[0] = address; 164 | if (readBytes(data,2)) 165 | { 166 | value = (((unsigned int)data[0]<<8)|(unsigned int)data[1]); 167 | return(1); 168 | } 169 | value = 0; 170 | return(0); 171 | } 172 | 173 | 174 | char SFE_BMP180::readBytes(unsigned char *values, char length) 175 | // Read an array of bytes from device 176 | // values: external array to hold data. Put starting register in values[0]. 177 | // length: number of bytes to read 178 | { 179 | char x; 180 | 181 | Wire.beginTransmission(BMP180_ADDR); 182 | Wire.write(values[0]); 183 | _error = Wire.endTransmission(); 184 | if (_error == 0) 185 | { 186 | Wire.requestFrom(BMP180_ADDR,length); 187 | while(Wire.available() != length) ; // wait until bytes are ready 188 | for(x=0;x 38 | #else 39 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 40 | #endif 41 | 42 | Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): 43 | WIDTH(w), HEIGHT(h) 44 | { 45 | _width = WIDTH; 46 | _height = HEIGHT; 47 | rotation = 0; 48 | cursor_y = cursor_x = 0; 49 | textsize = 1; 50 | textcolor = textbgcolor = 0xFFFF; 51 | wrap = true; 52 | } 53 | 54 | // Draw a circle outline 55 | void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, 56 | uint16_t color) { 57 | int16_t f = 1 - r; 58 | int16_t ddF_x = 1; 59 | int16_t ddF_y = -2 * r; 60 | int16_t x = 0; 61 | int16_t y = r; 62 | 63 | drawPixel(x0 , y0+r, color); 64 | drawPixel(x0 , y0-r, color); 65 | drawPixel(x0+r, y0 , color); 66 | drawPixel(x0-r, y0 , color); 67 | 68 | while (x= 0) { 70 | y--; 71 | ddF_y += 2; 72 | f += ddF_y; 73 | } 74 | x++; 75 | ddF_x += 2; 76 | f += ddF_x; 77 | 78 | drawPixel(x0 + x, y0 + y, color); 79 | drawPixel(x0 - x, y0 + y, color); 80 | drawPixel(x0 + x, y0 - y, color); 81 | drawPixel(x0 - x, y0 - y, color); 82 | drawPixel(x0 + y, y0 + x, color); 83 | drawPixel(x0 - y, y0 + x, color); 84 | drawPixel(x0 + y, y0 - x, color); 85 | drawPixel(x0 - y, y0 - x, color); 86 | } 87 | } 88 | 89 | void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, 90 | int16_t r, uint8_t cornername, uint16_t color) { 91 | int16_t f = 1 - r; 92 | int16_t ddF_x = 1; 93 | int16_t ddF_y = -2 * r; 94 | int16_t x = 0; 95 | int16_t y = r; 96 | 97 | while (x= 0) { 99 | y--; 100 | ddF_y += 2; 101 | f += ddF_y; 102 | } 103 | x++; 104 | ddF_x += 2; 105 | f += ddF_x; 106 | if (cornername & 0x4) { 107 | drawPixel(x0 + x, y0 + y, color); 108 | drawPixel(x0 + y, y0 + x, color); 109 | } 110 | if (cornername & 0x2) { 111 | drawPixel(x0 + x, y0 - y, color); 112 | drawPixel(x0 + y, y0 - x, color); 113 | } 114 | if (cornername & 0x8) { 115 | drawPixel(x0 - y, y0 + x, color); 116 | drawPixel(x0 - x, y0 + y, color); 117 | } 118 | if (cornername & 0x1) { 119 | drawPixel(x0 - y, y0 - x, color); 120 | drawPixel(x0 - x, y0 - y, color); 121 | } 122 | } 123 | } 124 | 125 | void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, 126 | uint16_t color) { 127 | drawFastVLine(x0, y0-r, 2*r+1, color); 128 | fillCircleHelper(x0, y0, r, 3, 0, color); 129 | } 130 | 131 | // Used to do circles and roundrects 132 | void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, 133 | uint8_t cornername, int16_t delta, uint16_t color) { 134 | 135 | int16_t f = 1 - r; 136 | int16_t ddF_x = 1; 137 | int16_t ddF_y = -2 * r; 138 | int16_t x = 0; 139 | int16_t y = r; 140 | 141 | while (x= 0) { 143 | y--; 144 | ddF_y += 2; 145 | f += ddF_y; 146 | } 147 | x++; 148 | ddF_x += 2; 149 | f += ddF_x; 150 | 151 | if (cornername & 0x1) { 152 | drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 153 | drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 154 | } 155 | if (cornername & 0x2) { 156 | drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 157 | drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 158 | } 159 | } 160 | } 161 | 162 | // Bresenham's algorithm - thx wikpedia 163 | void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, 164 | int16_t x1, int16_t y1, 165 | uint16_t color) { 166 | int16_t steep = abs(y1 - y0) > abs(x1 - x0); 167 | if (steep) { 168 | swap(x0, y0); 169 | swap(x1, y1); 170 | } 171 | 172 | if (x0 > x1) { 173 | swap(x0, x1); 174 | swap(y0, y1); 175 | } 176 | 177 | int16_t dx, dy; 178 | dx = x1 - x0; 179 | dy = abs(y1 - y0); 180 | 181 | int16_t err = dx / 2; 182 | int16_t ystep; 183 | 184 | if (y0 < y1) { 185 | ystep = 1; 186 | } else { 187 | ystep = -1; 188 | } 189 | 190 | for (; x0<=x1; x0++) { 191 | if (steep) { 192 | drawPixel(y0, x0, color); 193 | } else { 194 | drawPixel(x0, y0, color); 195 | } 196 | err -= dy; 197 | if (err < 0) { 198 | y0 += ystep; 199 | err += dx; 200 | } 201 | } 202 | } 203 | 204 | // Draw a rectangle 205 | void Adafruit_GFX::drawRect(int16_t x, int16_t y, 206 | int16_t w, int16_t h, 207 | uint16_t color) { 208 | drawFastHLine(x, y, w, color); 209 | drawFastHLine(x, y+h-1, w, color); 210 | drawFastVLine(x, y, h, color); 211 | drawFastVLine(x+w-1, y, h, color); 212 | } 213 | 214 | void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, 215 | int16_t h, uint16_t color) { 216 | // Update in subclasses if desired! 217 | drawLine(x, y, x, y+h-1, color); 218 | } 219 | 220 | void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, 221 | int16_t w, uint16_t color) { 222 | // Update in subclasses if desired! 223 | drawLine(x, y, x+w-1, y, color); 224 | } 225 | 226 | void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 227 | uint16_t color) { 228 | // Update in subclasses if desired! 229 | for (int16_t i=x; i= y1 >= y0) 281 | if (y0 > y1) { 282 | swap(y0, y1); swap(x0, x1); 283 | } 284 | if (y1 > y2) { 285 | swap(y2, y1); swap(x2, x1); 286 | } 287 | if (y0 > y1) { 288 | swap(y0, y1); swap(x0, x1); 289 | } 290 | 291 | if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 292 | a = b = x0; 293 | if(x1 < a) a = x1; 294 | else if(x1 > b) b = x1; 295 | if(x2 < a) a = x2; 296 | else if(x2 > b) b = x2; 297 | drawFastHLine(a, y0, b-a+1, color); 298 | return; 299 | } 300 | 301 | int16_t 302 | dx01 = x1 - x0, 303 | dy01 = y1 - y0, 304 | dx02 = x2 - x0, 305 | dy02 = y2 - y0, 306 | dx12 = x2 - x1, 307 | dy12 = y2 - y1, 308 | sa = 0, 309 | sb = 0; 310 | 311 | // For upper part of triangle, find scanline crossings for segments 312 | // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 313 | // is included here (and second loop will be skipped, avoiding a /0 314 | // error there), otherwise scanline y1 is skipped here and handled 315 | // in the second loop...which also avoids a /0 error here if y0=y1 316 | // (flat-topped triangle). 317 | if(y1 == y2) last = y1; // Include y1 scanline 318 | else last = y1-1; // Skip it 319 | 320 | for(y=y0; y<=last; y++) { 321 | a = x0 + sa / dy01; 322 | b = x0 + sb / dy02; 323 | sa += dx01; 324 | sb += dx02; 325 | /* longhand: 326 | a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 327 | b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 328 | */ 329 | if(a > b) swap(a,b); 330 | drawFastHLine(a, y, b-a+1, color); 331 | } 332 | 333 | // For lower part of triangle, find scanline crossings for segments 334 | // 0-2 and 1-2. This loop is skipped if y1=y2. 335 | sa = dx12 * (y - y1); 336 | sb = dx02 * (y - y0); 337 | for(; y<=y2; y++) { 338 | a = x1 + sa / dy12; 339 | b = x0 + sb / dy02; 340 | sa += dx12; 341 | sb += dx02; 342 | /* longhand: 343 | a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 344 | b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 345 | */ 346 | if(a > b) swap(a,b); 347 | drawFastHLine(a, y, b-a+1, color); 348 | } 349 | } 350 | 351 | void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, 352 | const uint8_t *bitmap, int16_t w, int16_t h, 353 | uint16_t color) { 354 | 355 | int16_t i, j, byteWidth = (w + 7) / 8; 356 | 357 | for(j=0; j> (i & 7))) { 360 | drawPixel(x+i, y+j, color); 361 | } 362 | } 363 | } 364 | } 365 | 366 | #if ARDUINO >= 100 367 | size_t Adafruit_GFX::write(uint8_t c) { 368 | #else 369 | void Adafruit_GFX::write(uint8_t c) { 370 | #endif 371 | if (c == '\n') { 372 | cursor_y += textsize*8; 373 | cursor_x = 0; 374 | } else if (c == '\r') { 375 | // skip em 376 | } else { 377 | drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); 378 | cursor_x += textsize*6; 379 | if (wrap && (cursor_x > (_width - textsize*6))) { 380 | cursor_y += textsize*8; 381 | cursor_x = 0; 382 | } 383 | } 384 | #if ARDUINO >= 100 385 | return 1; 386 | #endif 387 | } 388 | 389 | // Draw a character 390 | void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, 391 | uint16_t color, uint16_t bg, uint8_t size) { 392 | 393 | if((x >= _width) || // Clip right 394 | (y >= _height) || // Clip bottom 395 | ((x + 6 * size - 1) < 0) || // Clip left 396 | ((y + 8 * size - 1) < 0)) // Clip top 397 | return; 398 | 399 | for (int8_t i=0; i<6; i++ ) { 400 | uint8_t line; 401 | if (i == 5) 402 | line = 0x0; 403 | else 404 | line = pgm_read_byte(font+(c*5)+i); 405 | for (int8_t j = 0; j<8; j++) { 406 | if (line & 0x1) { 407 | if (size == 1) // default size 408 | drawPixel(x+i, y+j, color); 409 | else { // big size 410 | fillRect(x+(i*size), y+(j*size), size, size, color); 411 | } 412 | } else if (bg != color) { 413 | if (size == 1) // default size 414 | drawPixel(x+i, y+j, bg); 415 | else { // big size 416 | fillRect(x+i*size, y+j*size, size, size, bg); 417 | } 418 | } 419 | line >>= 1; 420 | } 421 | } 422 | } 423 | 424 | void Adafruit_GFX::setCursor(int16_t x, int16_t y) { 425 | cursor_x = x; 426 | cursor_y = y; 427 | } 428 | 429 | void Adafruit_GFX::setTextSize(uint8_t s) { 430 | textsize = (s > 0) ? s : 1; 431 | } 432 | 433 | void Adafruit_GFX::setTextColor(uint16_t c) { 434 | // For 'transparent' background, we'll set the bg 435 | // to the same as fg instead of using a flag 436 | textcolor = textbgcolor = c; 437 | } 438 | 439 | void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { 440 | textcolor = c; 441 | textbgcolor = b; 442 | } 443 | 444 | void Adafruit_GFX::setTextWrap(boolean w) { 445 | wrap = w; 446 | } 447 | 448 | uint8_t Adafruit_GFX::getRotation(void) { 449 | return rotation; 450 | } 451 | 452 | void Adafruit_GFX::setRotation(uint8_t x) { 453 | rotation = (x & 3); 454 | switch(rotation) { 455 | case 0: 456 | case 2: 457 | _width = WIDTH; 458 | _height = HEIGHT; 459 | break; 460 | case 1: 461 | case 3: 462 | _width = HEIGHT; 463 | _height = WIDTH; 464 | break; 465 | } 466 | } 467 | 468 | // Return the size of the display (per current rotation) 469 | int16_t Adafruit_GFX::width(void) { 470 | return _width; 471 | } 472 | 473 | int16_t Adafruit_GFX::height(void) { 474 | return _height; 475 | } 476 | 477 | void Adafruit_GFX::invertDisplay(boolean i) { 478 | // Do nothing, must be subclassed if supported 479 | } 480 | 481 | -------------------------------------------------------------------------------- /Tiny_altimeter_v1_04/libs/Adafruit_SSD1306/Adafruit_SSD1306.cpp: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is a library for our Monochrome OLEDs based on SSD1306 drivers 3 | 4 | Pick one up today in the adafruit shop! 5 | ------> http://www.adafruit.com/category/63_98 6 | 7 | These displays use SPI to communicate, 4 or 5 pins are required to 8 | interface 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. 15 | BSD license, check license.txt for more information 16 | All text above, and the splash screen below must be included in any redistribution 17 | *********************************************************************/ 18 | 19 | #include 20 | #ifndef __SAM3X8E__ 21 | #include 22 | #endif 23 | #include 24 | 25 | #include 26 | 27 | #include "Adafruit_GFX.h" 28 | #include "Adafruit_SSD1306.h" 29 | 30 | // the memory buffer for the LCD 31 | 32 | static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = { 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 37 | 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 44 | 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF, 45 | 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 46 | 0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8, 48 | 0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80, 50 | 0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01, 52 | 0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF, 53 | 0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00, 54 | 0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF, 55 | 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 56 | 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F, 58 | 0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 59 | 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03, 60 | 0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 61 | 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00, 62 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 63 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03, 64 | 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | #if (SSD1306_LCDHEIGHT == 64) 66 | 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F, 67 | 0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF, 68 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00, 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00, 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F, 75 | 0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0, 76 | 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 77 | 0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E, 78 | 0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC, 79 | 0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06, 80 | 0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8, 81 | 0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 85 | 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C, 86 | 0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 87 | 0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 88 | 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07, 89 | 0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 93 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 98 | #endif 99 | }; 100 | 101 | 102 | 103 | // the most basic function, set a single pixel 104 | void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) { 105 | if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) 106 | return; 107 | 108 | // check rotation, move pixel around if necessary 109 | switch (getRotation()) { 110 | case 1: 111 | swap(x, y); 112 | x = WIDTH - x - 1; 113 | break; 114 | case 2: 115 | x = WIDTH - x - 1; 116 | y = HEIGHT - y - 1; 117 | break; 118 | case 3: 119 | swap(x, y); 120 | y = HEIGHT - y - 1; 121 | break; 122 | } 123 | 124 | // x is which column 125 | if (color == WHITE) 126 | buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << (y&7)); 127 | else 128 | buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << (y&7)); 129 | } 130 | 131 | Adafruit_SSD1306::Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) { 132 | cs = CS; 133 | rst = RST; 134 | dc = DC; 135 | sclk = SCLK; 136 | sid = SID; 137 | hwSPI = false; 138 | } 139 | 140 | // constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset 141 | Adafruit_SSD1306::Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) { 142 | dc = DC; 143 | rst = RST; 144 | cs = CS; 145 | hwSPI = true; 146 | } 147 | 148 | // initializer for I2C - we only indicate the reset pin! 149 | Adafruit_SSD1306::Adafruit_SSD1306(int8_t reset) : 150 | Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) { 151 | sclk = dc = cs = sid = -1; 152 | rst = reset; 153 | } 154 | 155 | 156 | void Adafruit_SSD1306::begin(uint8_t vccstate, uint8_t i2caddr) { 157 | _vccstate = vccstate; 158 | _i2caddr = i2caddr; 159 | 160 | // set pin directions 161 | if (sid != -1){ 162 | pinMode(dc, OUTPUT); 163 | pinMode(cs, OUTPUT); 164 | csport = portOutputRegister(digitalPinToPort(cs)); 165 | cspinmask = digitalPinToBitMask(cs); 166 | dcport = portOutputRegister(digitalPinToPort(dc)); 167 | dcpinmask = digitalPinToBitMask(dc); 168 | if (!hwSPI){ 169 | // set pins for software-SPI 170 | pinMode(sid, OUTPUT); 171 | pinMode(sclk, OUTPUT); 172 | clkport = portOutputRegister(digitalPinToPort(sclk)); 173 | clkpinmask = digitalPinToBitMask(sclk); 174 | mosiport = portOutputRegister(digitalPinToPort(sid)); 175 | mosipinmask = digitalPinToBitMask(sid); 176 | } 177 | if (hwSPI){ 178 | SPI.begin (); 179 | #ifdef __SAM3X8E__ 180 | SPI.setClockDivider (9); // 9.3 MHz 181 | #else 182 | SPI.setClockDivider (SPI_CLOCK_DIV2); // 8 MHz 183 | #endif 184 | } 185 | } 186 | else 187 | { 188 | // I2C Init 189 | Wire.begin(); 190 | #ifdef __SAM3X8E__ 191 | // Force 400 KHz I2C, rawr! (Uses pins 20, 21 for SDA, SCL) 192 | TWI1->TWI_CWGR = 0; 193 | TWI1->TWI_CWGR = ((VARIANT_MCK / (2 * 400000)) - 4) * 0x101; 194 | #endif 195 | } 196 | 197 | // Setup reset pin direction (used by both SPI and I2C) 198 | pinMode(rst, OUTPUT); 199 | digitalWrite(rst, HIGH); 200 | // VDD (3.3V) goes high at start, lets just chill for a ms 201 | delay(1); 202 | // bring reset low 203 | digitalWrite(rst, LOW); 204 | // wait 10ms 205 | delay(10); 206 | // bring out of reset 207 | digitalWrite(rst, HIGH); 208 | // turn on VCC (9V?) 209 | 210 | #if defined SSD1306_128_32 211 | // Init sequence for 128x32 OLED module 212 | ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE 213 | ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 214 | ssd1306_command(0x80); // the suggested ratio 0x80 215 | ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8 216 | ssd1306_command(0x1F); 217 | ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3 218 | ssd1306_command(0x0); // no offset 219 | ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 220 | ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D 221 | if (vccstate == SSD1306_EXTERNALVCC) 222 | { ssd1306_command(0x10); } 223 | else 224 | { ssd1306_command(0x14); } 225 | ssd1306_command(SSD1306_MEMORYMODE); // 0x20 226 | ssd1306_command(0x00); // 0x0 act like ks0108 227 | ssd1306_command(SSD1306_SEGREMAP | 0x1); 228 | ssd1306_command(SSD1306_COMSCANDEC); 229 | ssd1306_command(SSD1306_SETCOMPINS); // 0xDA 230 | ssd1306_command(0x02); 231 | ssd1306_command(SSD1306_SETCONTRAST); // 0x81 232 | ssd1306_command(0x8F); 233 | ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9 234 | if (vccstate == SSD1306_EXTERNALVCC) 235 | { ssd1306_command(0x22); } 236 | else 237 | { ssd1306_command(0xF1); } 238 | ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB 239 | ssd1306_command(0x40); 240 | ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4 241 | ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6 242 | #endif 243 | 244 | #if defined SSD1306_128_64 245 | // Init sequence for 128x64 OLED module 246 | ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE 247 | ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 248 | ssd1306_command(0x80); // the suggested ratio 0x80 249 | ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8 250 | ssd1306_command(0x3F); 251 | ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3 252 | ssd1306_command(0x0); // no offset 253 | ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 254 | ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D 255 | if (vccstate == SSD1306_EXTERNALVCC) 256 | { ssd1306_command(0x10); } 257 | else 258 | { ssd1306_command(0x14); } 259 | ssd1306_command(SSD1306_MEMORYMODE); // 0x20 260 | ssd1306_command(0x00); // 0x0 act like ks0108 261 | ssd1306_command(SSD1306_SEGREMAP | 0x1); 262 | ssd1306_command(SSD1306_COMSCANDEC); 263 | ssd1306_command(SSD1306_SETCOMPINS); // 0xDA 264 | ssd1306_command(0x12); 265 | ssd1306_command(SSD1306_SETCONTRAST); // 0x81 266 | if (vccstate == SSD1306_EXTERNALVCC) 267 | { ssd1306_command(0x9F); } 268 | else 269 | { ssd1306_command(0xCF); } 270 | ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9 271 | if (vccstate == SSD1306_EXTERNALVCC) 272 | { ssd1306_command(0x22); } 273 | else 274 | { ssd1306_command(0xF1); } 275 | ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB 276 | ssd1306_command(0x40); 277 | ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4 278 | ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6 279 | #endif 280 | 281 | ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel 282 | } 283 | 284 | 285 | void Adafruit_SSD1306::invertDisplay(uint8_t i) { 286 | if (i) { 287 | ssd1306_command(SSD1306_INVERTDISPLAY); 288 | } else { 289 | ssd1306_command(SSD1306_NORMALDISPLAY); 290 | } 291 | } 292 | 293 | void Adafruit_SSD1306::ssd1306_command(uint8_t c) { 294 | if (sid != -1) 295 | { 296 | // SPI 297 | //digitalWrite(cs, HIGH); 298 | *csport |= cspinmask; 299 | //digitalWrite(dc, LOW); 300 | *dcport &= ~dcpinmask; 301 | //digitalWrite(cs, LOW); 302 | *csport &= ~cspinmask; 303 | fastSPIwrite(c); 304 | //digitalWrite(cs, HIGH); 305 | *csport |= cspinmask; 306 | } 307 | else 308 | { 309 | // I2C 310 | uint8_t control = 0x00; // Co = 0, D/C = 0 311 | Wire.beginTransmission(_i2caddr); 312 | Wire.write(control); 313 | Wire.write(c); 314 | Wire.endTransmission(); 315 | } 316 | } 317 | 318 | // startscrollright 319 | // Activate a right handed scroll for rows start through stop 320 | // Hint, the display is 16 rows tall. To scroll the whole display, run: 321 | // display.scrollright(0x00, 0x0F) 322 | void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop){ 323 | ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL); 324 | ssd1306_command(0X00); 325 | ssd1306_command(start); 326 | ssd1306_command(0X00); 327 | ssd1306_command(stop); 328 | ssd1306_command(0X00); 329 | ssd1306_command(0XFF); 330 | ssd1306_command(SSD1306_ACTIVATE_SCROLL); 331 | } 332 | 333 | // startscrollleft 334 | // Activate a right handed scroll for rows start through stop 335 | // Hint, the display is 16 rows tall. To scroll the whole display, run: 336 | // display.scrollright(0x00, 0x0F) 337 | void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop){ 338 | ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL); 339 | ssd1306_command(0X00); 340 | ssd1306_command(start); 341 | ssd1306_command(0X00); 342 | ssd1306_command(stop); 343 | ssd1306_command(0X00); 344 | ssd1306_command(0XFF); 345 | ssd1306_command(SSD1306_ACTIVATE_SCROLL); 346 | } 347 | 348 | // startscrolldiagright 349 | // Activate a diagonal scroll for rows start through stop 350 | // Hint, the display is 16 rows tall. To scroll the whole display, run: 351 | // display.scrollright(0x00, 0x0F) 352 | void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop){ 353 | ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA); 354 | ssd1306_command(0X00); 355 | ssd1306_command(SSD1306_LCDHEIGHT); 356 | ssd1306_command(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL); 357 | ssd1306_command(0X00); 358 | ssd1306_command(start); 359 | ssd1306_command(0X00); 360 | ssd1306_command(stop); 361 | ssd1306_command(0X01); 362 | ssd1306_command(SSD1306_ACTIVATE_SCROLL); 363 | } 364 | 365 | // startscrolldiagleft 366 | // Activate a diagonal scroll for rows start through stop 367 | // Hint, the display is 16 rows tall. To scroll the whole display, run: 368 | // display.scrollright(0x00, 0x0F) 369 | void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop){ 370 | ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA); 371 | ssd1306_command(0X00); 372 | ssd1306_command(SSD1306_LCDHEIGHT); 373 | ssd1306_command(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL); 374 | ssd1306_command(0X00); 375 | ssd1306_command(start); 376 | ssd1306_command(0X00); 377 | ssd1306_command(stop); 378 | ssd1306_command(0X01); 379 | ssd1306_command(SSD1306_ACTIVATE_SCROLL); 380 | } 381 | 382 | void Adafruit_SSD1306::stopscroll(void){ 383 | ssd1306_command(SSD1306_DEACTIVATE_SCROLL); 384 | } 385 | 386 | // Dim the display 387 | // dim = true: display is dimmed 388 | // dim = false: display is normal 389 | void Adafruit_SSD1306::dim(boolean dim) { 390 | uint8_t contrast; 391 | 392 | if (dim) { 393 | contrast = 0; // Dimmed display 394 | } else { 395 | if (_vccstate == SSD1306_EXTERNALVCC) { 396 | contrast = 0x9F; 397 | } else { 398 | contrast = 0xCF; 399 | } 400 | } 401 | // the range of contrast to too small to be really useful 402 | // it is useful to dim the display 403 | ssd1306_command(SSD1306_SETCONTRAST); 404 | ssd1306_command(contrast); 405 | } 406 | 407 | void Adafruit_SSD1306::ssd1306_data(uint8_t c) { 408 | if (sid != -1) 409 | { 410 | // SPI 411 | //digitalWrite(cs, HIGH); 412 | *csport |= cspinmask; 413 | //digitalWrite(dc, HIGH); 414 | *dcport |= dcpinmask; 415 | //digitalWrite(cs, LOW); 416 | *csport &= ~cspinmask; 417 | fastSPIwrite(c); 418 | //digitalWrite(cs, HIGH); 419 | *csport |= cspinmask; 420 | } 421 | else 422 | { 423 | // I2C 424 | uint8_t control = 0x40; // Co = 0, D/C = 1 425 | Wire.beginTransmission(_i2caddr); 426 | Wire.write(control); 427 | Wire.write(c); 428 | Wire.endTransmission(); 429 | } 430 | } 431 | 432 | void Adafruit_SSD1306::display(void) { 433 | ssd1306_command(SSD1306_COLUMNADDR); 434 | ssd1306_command(0); // Column start address (0 = reset) 435 | ssd1306_command(127); // Column end address (127 = reset) 436 | 437 | ssd1306_command(SSD1306_PAGEADDR); 438 | ssd1306_command(0); // Page start address (0 = reset) 439 | ssd1306_command((SSD1306_LCDHEIGHT == 64) ? 7 : 3); // Page end address 440 | 441 | if (sid != -1) 442 | { 443 | // SPI 444 | *csport |= cspinmask; 445 | *dcport |= dcpinmask; 446 | *csport &= ~cspinmask; 447 | 448 | for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) { 449 | fastSPIwrite(buffer[i]); 450 | //ssd1306_data(buffer[i]); 451 | } 452 | *csport |= cspinmask; 453 | } 454 | else 455 | { 456 | // save I2C bitrate 457 | #ifndef __SAM3X8E__ 458 | uint8_t twbrbackup = TWBR; 459 | TWBR = 12; // upgrade to 400KHz! 460 | #endif 461 | 462 | //Serial.println(TWBR, DEC); 463 | //Serial.println(TWSR & 0x3, DEC); 464 | 465 | // I2C 466 | for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) { 467 | // send a bunch of data in one xmission 468 | Wire.beginTransmission(_i2caddr); 469 | Wire.write(0x40); 470 | for (uint8_t x=0; x<16; x++) { 471 | Wire.write(buffer[i]); 472 | i++; 473 | } 474 | i--; 475 | Wire.endTransmission(); 476 | } 477 | #ifndef __SAM3X8E__ 478 | TWBR = twbrbackup; 479 | #endif 480 | } 481 | } 482 | 483 | // clear everything 484 | void Adafruit_SSD1306::clearDisplay(void) { 485 | memset(buffer, 0, (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8)); 486 | } 487 | 488 | 489 | inline void Adafruit_SSD1306::fastSPIwrite(uint8_t d) { 490 | 491 | if(hwSPI) { 492 | (void)SPI.transfer(d); 493 | } else { 494 | for(uint8_t bit = 0x80; bit; bit >>= 1) { 495 | *clkport &= ~clkpinmask; 496 | if(d & bit) *mosiport |= mosipinmask; 497 | else *mosiport &= ~mosipinmask; 498 | *clkport |= clkpinmask; 499 | } 500 | } 501 | //*csport |= cspinmask; 502 | } 503 | 504 | void Adafruit_SSD1306::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { 505 | boolean bSwap = false; 506 | switch(rotation) { 507 | case 0: 508 | // 0 degree rotation, do nothing 509 | break; 510 | case 1: 511 | // 90 degree rotation, swap x & y for rotation, then invert x 512 | bSwap = true; 513 | swap(x, y); 514 | x = WIDTH - x - 1; 515 | break; 516 | case 2: 517 | // 180 degree rotation, invert x and y - then shift y around for height. 518 | x = WIDTH - x - 1; 519 | y = HEIGHT - y - 1; 520 | x -= (w-1); 521 | break; 522 | case 3: 523 | // 270 degree rotation, swap x & y for rotation, then invert y and adjust y for w (not to become h) 524 | bSwap = true; 525 | swap(x, y); 526 | y = HEIGHT - y - 1; 527 | y -= (w-1); 528 | break; 529 | } 530 | 531 | if(bSwap) { 532 | drawFastVLineInternal(x, y, w, color); 533 | } else { 534 | drawFastHLineInternal(x, y, w, color); 535 | } 536 | } 537 | 538 | void Adafruit_SSD1306::drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) { 539 | // Do bounds/limit checks 540 | if(y < 0 || y >= HEIGHT) { return; } 541 | 542 | // make sure we don't try to draw below 0 543 | if(x < 0) { 544 | w += x; 545 | x = 0; 546 | } 547 | 548 | // make sure we don't go off the edge of the display 549 | if( (x + w) > WIDTH) { 550 | w = (HEIGHT- x); 551 | } 552 | 553 | // if our width is now negative, punt 554 | if(w <= 0) { return; } 555 | 556 | // set up the pointer for movement through the buffer 557 | register uint8_t *pBuf = buffer; 558 | // adjust the buffer pointer for the current row 559 | pBuf += ((y/8) * SSD1306_LCDWIDTH); 560 | // and offset x columns in 561 | pBuf += x; 562 | 563 | register uint8_t mask = 1 << (y&7); 564 | 565 | if(color == WHITE) { 566 | while(w--) { *pBuf++ |= mask; } 567 | } else { 568 | mask = ~mask; 569 | while(w--) { *pBuf++ &= mask; } 570 | } 571 | } 572 | 573 | void Adafruit_SSD1306::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { 574 | bool bSwap = false; 575 | switch(rotation) { 576 | case 0: 577 | break; 578 | case 1: 579 | // 90 degree rotation, swap x & y for rotation, then invert x and adjust x for h (now to become w) 580 | bSwap = true; 581 | swap(x, y); 582 | x = WIDTH - x - 1; 583 | x -= (h-1); 584 | break; 585 | case 2: 586 | // 180 degree rotation, invert x and y - then shift y around for height. 587 | x = WIDTH - x - 1; 588 | y = HEIGHT - y - 1; 589 | y -= (h-1); 590 | break; 591 | case 3: 592 | // 270 degree rotation, swap x & y for rotation, then invert y 593 | bSwap = true; 594 | swap(x, y); 595 | y = HEIGHT - y - 1; 596 | break; 597 | } 598 | 599 | if(bSwap) { 600 | drawFastHLineInternal(x, y, h, color); 601 | } else { 602 | drawFastVLineInternal(x, y, h, color); 603 | } 604 | } 605 | 606 | 607 | void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color) { 608 | 609 | // do nothing if we're off the left or right side of the screen 610 | if(x < 0 || x >= WIDTH) { return; } 611 | 612 | // make sure we don't try to draw below 0 613 | if(__y < 0) { 614 | // __y is negative, this will subtract enough from __h to account for __y being 0 615 | __h += __y; 616 | __y = 0; 617 | 618 | } 619 | 620 | // make sure we don't go past the height of the display 621 | if( (__y + __h) > HEIGHT) { 622 | __h = (HEIGHT - __y); 623 | } 624 | 625 | // if our height is now negative, punt 626 | if(__h <= 0) { 627 | return; 628 | } 629 | 630 | // this display doesn't need ints for coordinates, use local byte registers for faster juggling 631 | register uint8_t y = __y; 632 | register uint8_t h = __h; 633 | 634 | 635 | // set up the pointer for fast movement through the buffer 636 | register uint8_t *pBuf = buffer; 637 | // adjust the buffer pointer for the current row 638 | pBuf += ((y/8) * SSD1306_LCDWIDTH); 639 | // and offset x columns in 640 | pBuf += x; 641 | 642 | // do the first partial byte, if necessary - this requires some masking 643 | register uint8_t mod = (y&7); 644 | if(mod) { 645 | // mask off the high n bits we want to set 646 | mod = 8-mod; 647 | 648 | // note - lookup table results in a nearly 10% performance improvement in fill* functions 649 | // register uint8_t mask = ~(0xFF >> (mod)); 650 | static uint8_t premask[8] = {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; 651 | register uint8_t mask = premask[mod]; 652 | 653 | // adjust the mask if we're not going to reach the end of this byte 654 | if( h < mod) { 655 | mask &= (0XFF >> (mod-h)); 656 | } 657 | 658 | if(color == WHITE) { 659 | *pBuf |= mask; 660 | } else { 661 | *pBuf &= ~mask; 662 | } 663 | 664 | // fast exit if we're done here! 665 | if(h= 8) { 675 | // store a local value to work with 676 | register uint8_t val = (color == WHITE) ? 255 : 0; 677 | 678 | do { 679 | // write our value in 680 | *pBuf = val; 681 | 682 | // adjust the buffer forward 8 rows worth of data 683 | pBuf += SSD1306_LCDWIDTH; 684 | 685 | // adjust h & y (there's got to be a faster way for me to do this, but this should still help a fair bit for now) 686 | h -= 8; 687 | } while(h >= 8); 688 | } 689 | 690 | // now do the final partial byte, if necessary 691 | if(h) { 692 | mod = h & 7; 693 | // this time we want to mask the low bits of the byte, vs the high bits we did above 694 | // register uint8_t mask = (1 << mod) - 1; 695 | // note - lookup table results in a nearly 10% performance improvement in fill* functions 696 | static uint8_t postmask[8] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F }; 697 | register uint8_t mask = postmask[mod]; 698 | if(color == WHITE) { 699 | *pBuf |= mask; 700 | } else { 701 | *pBuf &= ~mask; 702 | } 703 | } 704 | } 705 | 706 | --------------------------------------------------------------------------------