You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

504 lines
14 KiB

4 years ago
  1. /**************************************************************************
  2. This is an example for our Monochrome OLEDs based on SSD1306 drivers
  3. Pick one up today in the adafruit shop!
  4. ------> http://www.adafruit.com/category/63_98
  5. This example is for a 128x32 pixel display using I2C to communicate
  6. 3 pins are required to interface (two I2C and one reset).
  7. Adafruit invests time and resources providing this open
  8. source code, please support Adafruit and open-source
  9. hardware by purchasing products from Adafruit!
  10. Written by Limor Fried/Ladyada for Adafruit Industries,
  11. with contributions from the open source community.
  12. BSD license, check license.txt for more information
  13. All text above, and the splash screen below must be
  14. included in any redistribution.
  15. **************************************************************************/
  16. #include <SPI.h>
  17. #include <Wire.h>
  18. #include <Adafruit_GFX.h>
  19. #include <Adafruit_SSD1306.h>
  20. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  21. #define SCREEN_HEIGHT 32 // OLED display height, in pixels
  22. // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
  23. #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
  24. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  25. #define NUMFLAKES 10 // Number of snowflakes in the animation example
  26. #define LOGO_HEIGHT 16
  27. #define LOGO_WIDTH 16
  28. static const unsigned char PROGMEM logo_bmp[] =
  29. { B00000000, B11000000,
  30. B00000001, B11000000,
  31. B00000001, B11000000,
  32. B00000011, B11100000,
  33. B11110011, B11100000,
  34. B11111110, B11111000,
  35. B01111110, B11111111,
  36. B00110011, B10011111,
  37. B00011111, B11111100,
  38. B00001101, B01110000,
  39. B00011011, B10100000,
  40. B00111111, B11100000,
  41. B00111111, B11110000,
  42. B01111100, B11110000,
  43. B01110000, B01110000,
  44. B00000000, B00110000 };
  45. void setup() {
  46. Serial.begin(9600);
  47. // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  48. if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
  49. Serial.println(F("SSD1306 allocation failed"));
  50. for(;;); // Don't proceed, loop forever
  51. }
  52. // Show initial display buffer contents on the screen --
  53. // the library initializes this with an Adafruit splash screen.
  54. display.display();
  55. delay(2000); // Pause for 2 seconds
  56. // Clear the buffer
  57. display.clearDisplay();
  58. // Draw a single pixel in white
  59. display.drawPixel(10, 10, SSD1306_WHITE);
  60. // Show the display buffer on the screen. You MUST call display() after
  61. // drawing commands to make them visible on screen!
  62. display.display();
  63. delay(2000);
  64. // display.display() is NOT necessary after every single drawing command,
  65. // unless that's what you want...rather, you can batch up a bunch of
  66. // drawing operations and then update the screen all at once by calling
  67. // display.display(). These examples demonstrate both approaches...
  68. /*testdrawline(); // Draw many lines
  69. testdrawrect(); // Draw rectangles (outlines)
  70. testfillrect(); // Draw rectangles (filled)
  71. testdrawcircle(); // Draw circles (outlines)
  72. testfillcircle(); // Draw circles (filled)
  73. testdrawroundrect(); // Draw rounded rectangles (outlines)
  74. testfillroundrect(); // Draw rounded rectangles (filled)
  75. testdrawtriangle(); // Draw triangles (outlines)
  76. testfilltriangle(); // Draw triangles (filled)
  77. testdrawchar(); // Draw characters of the default font
  78. testdrawstyles(); // Draw 'stylized' characters
  79. testscrolltext(); // Draw scrolling text
  80. testdrawbitmap(); // Draw a small bitmap image
  81. // Invert and restore display, pausing in-between
  82. display.invertDisplay(true);
  83. delay(1000);
  84. display.invertDisplay(false);
  85. delay(1000);*/
  86. //testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
  87. }
  88. void loop() {
  89. testdrawchar2(); // Draw scrolling text
  90. delay(2000);
  91. while(1){
  92. display.clearDisplay();
  93. testdrawchar3(); // Draw scrolling text
  94. }
  95. }
  96. double GetTemp(void)
  97. {
  98. unsigned int wADC;
  99. double t;
  100. // The internal temperature has to be used
  101. // with the internal reference of 1.1V.
  102. // Channel 8 can not be selected with
  103. // the analogRead function yet.
  104. // Set the internal reference and mux.
  105. ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
  106. ADCSRA |= _BV(ADEN); // enable the ADC
  107. delay(20); // wait for voltages to become stable.
  108. ADCSRA |= _BV(ADSC); // Start the ADC
  109. // Detect end-of-conversion
  110. while (bit_is_set(ADCSRA,ADSC));
  111. // Reading register "ADCW" takes care of how to read ADCL and ADCH.
  112. wADC = ADCW;
  113. // The offset of 324.31 could be wrong. It is just an indication.
  114. t = (wADC - 324.31 ) / 1.22;
  115. // The returned temperature is in degrees Celsius.
  116. return (t);
  117. }
  118. void testdrawline() {
  119. int16_t i;
  120. display.clearDisplay(); // Clear display buffer
  121. for(i=0; i<display.width(); i+=4) {
  122. display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
  123. display.display(); // Update screen with each newly-drawn line
  124. delay(1);
  125. }
  126. for(i=0; i<display.height(); i+=4) {
  127. display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
  128. display.display();
  129. delay(1);
  130. }
  131. delay(250);
  132. display.clearDisplay();
  133. for(i=0; i<display.width(); i+=4) {
  134. display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
  135. display.display();
  136. delay(1);
  137. }
  138. for(i=display.height()-1; i>=0; i-=4) {
  139. display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
  140. display.display();
  141. delay(1);
  142. }
  143. delay(250);
  144. display.clearDisplay();
  145. for(i=display.width()-1; i>=0; i-=4) {
  146. display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
  147. display.display();
  148. delay(1);
  149. }
  150. for(i=display.height()-1; i>=0; i-=4) {
  151. display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
  152. display.display();
  153. delay(1);
  154. }
  155. delay(250);
  156. display.clearDisplay();
  157. for(i=0; i<display.height(); i+=4) {
  158. display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
  159. display.display();
  160. delay(1);
  161. }
  162. for(i=0; i<display.width(); i+=4) {
  163. display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
  164. display.display();
  165. delay(1);
  166. }
  167. delay(2000); // Pause for 2 seconds
  168. }
  169. void testdrawrect(void) {
  170. display.clearDisplay();
  171. for(int16_t i=0; i<display.height()/2; i+=2) {
  172. display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);
  173. display.display(); // Update screen with each newly-drawn rectangle
  174. delay(1);
  175. }
  176. delay(2000);
  177. }
  178. void testfillrect(void) {
  179. display.clearDisplay();
  180. for(int16_t i=0; i<display.height()/2; i+=3) {
  181. // The INVERSE color is used so rectangles alternate white/black
  182. display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE);
  183. display.display(); // Update screen with each newly-drawn rectangle
  184. delay(1);
  185. }
  186. delay(2000);
  187. }
  188. void testdrawcircle(void) {
  189. display.clearDisplay();
  190. for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
  191. display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE);
  192. display.display();
  193. delay(1);
  194. }
  195. delay(2000);
  196. }
  197. void testfillcircle(void) {
  198. display.clearDisplay();
  199. for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
  200. // The INVERSE color is used so circles alternate white/black
  201. display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);
  202. display.display(); // Update screen with each newly-drawn circle
  203. delay(1);
  204. }
  205. delay(2000);
  206. }
  207. void testdrawroundrect(void) {
  208. display.clearDisplay();
  209. for(int16_t i=0; i<display.height()/2-2; i+=2) {
  210. display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
  211. display.height()/4, SSD1306_WHITE);
  212. display.display();
  213. delay(1);
  214. }
  215. delay(2000);
  216. }
  217. void testfillroundrect(void) {
  218. display.clearDisplay();
  219. for(int16_t i=0; i<display.height()/2-2; i+=2) {
  220. // The INVERSE color is used so round-rects alternate white/black
  221. display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
  222. display.height()/4, SSD1306_INVERSE);
  223. display.display();
  224. delay(1);
  225. }
  226. delay(2000);
  227. }
  228. void testdrawtriangle(void) {
  229. display.clearDisplay();
  230. for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
  231. display.drawTriangle(
  232. display.width()/2 , display.height()/2-i,
  233. display.width()/2-i, display.height()/2+i,
  234. display.width()/2+i, display.height()/2+i, SSD1306_WHITE);
  235. display.display();
  236. delay(1);
  237. }
  238. delay(2000);
  239. }
  240. void testfilltriangle(void) {
  241. display.clearDisplay();
  242. for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
  243. // The INVERSE color is used so triangles alternate white/black
  244. display.fillTriangle(
  245. display.width()/2 , display.height()/2-i,
  246. display.width()/2-i, display.height()/2+i,
  247. display.width()/2+i, display.height()/2+i, SSD1306_INVERSE);
  248. display.display();
  249. delay(1);
  250. }
  251. delay(2000);
  252. }
  253. void testdrawchar(void) {
  254. display.clearDisplay();
  255. display.setTextSize(1); // Normal 1:1 pixel scale
  256. display.setTextColor(SSD1306_WHITE); // Draw white text
  257. display.setCursor(0, 0); // Start at top-left corner
  258. display.cp437(true); // Use full 256 char 'Code Page 437' font
  259. // Not all the characters will fit on the display. This is normal.
  260. // Library will draw what it can and the rest will be clipped.
  261. for(int16_t i=0; i<256; i++) {
  262. if(i == '\n') display.write(' ');
  263. else display.write(i);
  264. }
  265. display.display();
  266. delay(2000);
  267. }
  268. void testdrawchar2(void) {
  269. display.clearDisplay();
  270. display.setTextSize(1); // Normal 1:1 pixel scale
  271. display.setTextColor(SSD1306_WHITE); // Draw white text
  272. display.setCursor(0, 0); // Start at top-left corner
  273. display.cp437(true); // Use full 256 char 'Code Page 437' font
  274. display.println(F(" Steak Electronics"));
  275. display.display();
  276. delay(2000);
  277. }
  278. void testdrawchar3(void) {
  279. display.clearDisplay();
  280. display.setTextSize(1); // Normal 1:1 pixel scale
  281. display.setTextColor(SSD1306_WHITE); // Draw white text
  282. display.setCursor(0, 10); // Start at top-left corner
  283. display.cp437(true); // Use full 256 char 'Code Page 437' font
  284. display.print("Temp: ");
  285. display.println(GetTemp(),1);
  286. display.display();
  287. delay(200);
  288. }
  289. void testdrawstyles(void) {
  290. display.clearDisplay();
  291. display.setTextSize(1); // Normal 1:1 pixel scale
  292. display.setTextColor(SSD1306_WHITE); // Draw white text
  293. display.setCursor(0,0); // Start at top-left corner
  294. display.println(F("Hello, world!"));
  295. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
  296. display.println(3.141592);
  297. display.setTextSize(2); // Draw 2X-scale text
  298. display.setTextColor(SSD1306_WHITE);
  299. display.print(F("0x")); display.println(0xDEADBEEF, HEX);
  300. display.display();
  301. delay(2000);
  302. }
  303. void testscrolltext(void) {
  304. display.clearDisplay();
  305. display.setTextSize(2); // Draw 2X-scale text
  306. display.setTextColor(SSD1306_WHITE);
  307. display.setCursor(10, 0);
  308. display.println(F("scroll"));
  309. display.display(); // Show initial text
  310. delay(100);
  311. // Scroll in various directions, pausing in-between:
  312. display.startscrollright(0x00, 0x0F);
  313. delay(2000);
  314. display.stopscroll();
  315. delay(1000);
  316. display.startscrollleft(0x00, 0x0F);
  317. delay(2000);
  318. display.stopscroll();
  319. delay(1000);
  320. display.startscrolldiagright(0x00, 0x07);
  321. delay(2000);
  322. display.startscrolldiagleft(0x00, 0x07);
  323. delay(2000);
  324. display.stopscroll();
  325. delay(1000);
  326. }
  327. void testscrolltext2(void) {
  328. display.clearDisplay();
  329. display.setTextSize(2); // Draw 2X-scale text
  330. display.setTextColor(SSD1306_WHITE);
  331. display.setCursor(10, 0);
  332. display.println(F("5318008"));
  333. display.display(); // Show initial text
  334. delay(100);
  335. // Scroll in various directions, pausing in-between:
  336. display.startscrollright(0x00, 0x0F);
  337. delay(2000);
  338. display.stopscroll();
  339. delay(1000);
  340. display.startscrollleft(0x00, 0x0F);
  341. delay(2000);
  342. display.stopscroll();
  343. delay(1000);
  344. display.startscrolldiagright(0x00, 0x07);
  345. delay(2000);
  346. display.startscrolldiagleft(0x00, 0x07);
  347. delay(2000);
  348. display.stopscroll();
  349. delay(1000);
  350. }
  351. void testdrawbitmap(void) {
  352. display.clearDisplay();
  353. display.drawBitmap(
  354. (display.width() - LOGO_WIDTH ) / 2,
  355. (display.height() - LOGO_HEIGHT) / 2,
  356. logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  357. display.display();
  358. delay(1000);
  359. }
  360. #define XPOS 0 // Indexes into the 'icons' array in function below
  361. #define YPOS 1
  362. #define DELTAY 2
  363. void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  364. int8_t f, icons[NUMFLAKES][3];
  365. // Initialize 'snowflake' positions
  366. for(f=0; f< NUMFLAKES; f++) {
  367. icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
  368. icons[f][YPOS] = -LOGO_HEIGHT;
  369. icons[f][DELTAY] = random(1, 6);
  370. Serial.print(F("x: "));
  371. Serial.print(icons[f][XPOS], DEC);
  372. Serial.print(F(" y: "));
  373. Serial.print(icons[f][YPOS], DEC);
  374. Serial.print(F(" dy: "));
  375. Serial.println(icons[f][DELTAY], DEC);
  376. }
  377. for(;;) { // Loop forever...
  378. display.clearDisplay(); // Clear the display buffer
  379. // Draw each snowflake:
  380. for(f=0; f< NUMFLAKES; f++) {
  381. display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);
  382. }
  383. display.display(); // Show the display buffer on the screen
  384. delay(200); // Pause for 1/10 second
  385. // Then update coordinates of each flake...
  386. for(f=0; f< NUMFLAKES; f++) {
  387. icons[f][YPOS] += icons[f][DELTAY];
  388. // If snowflake is off the bottom of the screen...
  389. if (icons[f][YPOS] >= display.height()) {
  390. // Reinitialize to a random position, just off the top
  391. icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
  392. icons[f][YPOS] = -LOGO_HEIGHT;
  393. icons[f][DELTAY] = random(1, 6);
  394. }
  395. }
  396. }
  397. }