mingzhi080218 发表于 2016-4-24 23:33:17

星期天在家弄了个SSD1331彩色OLED的小程序

本帖最后由 mingzhi080218 于 2016-4-24 23:33 编辑

星期天在家无事摆弄了一下很久之前买的OLED模块,闭关两天写了一个温湿度监测的小程序。
材料:1.MEGA 2560主板 2.DHT11 3.蜂鸣器 4.光敏电阻5.按键开关6.电位器7.火焰传感器 8.SSD1331彩色OLED(其中2-6在一个扩展板上)
主要功能:通过中断控制屏幕间切换和关闭,第一屏用曲线图显示温湿度变化,发现火源时蜂鸣器报警,温度大于33度时屏幕提示,预留了煤气报警的图形警告界面,等买了气体传感器再说;第二屏为数字显示温湿度数据及模拟温度计,模拟温度计还没有画太精准,本人数字实在太差算不来;第三屏没有想好做什么,随便画了个雷达图玩, 第四屏清屏。
先上图看下效果,做的很粗糙,图片也不是太清晰,各位凑合着看吧,也请各位大神多多指导。
第一屏:

第二屏:

第三屏:


面临的问题:
1.DHT11精度不够,需要更换精度更高的传感器?
2.SSD1331的刷新问题,目前用的库在工作时刷新不是太快,如要清屏或是画实心图形时就会闪烁,数字会产生重影。
3.按键输入信号抖动厉害,不能实现预定的功能。

第一次发贴不是太熟悉这个编辑器,随后再放代码和库文件。我是新手,请大神们手下留情。
(程序中用到的库: dht11,Adafruit_GFX,Adafruit_SSD1331)

mingzhi080218 发表于 2016-4-24 23:34:25

看看能不能占个沙发。请大神们多多帮助啊!

davidce 发表于 2016-4-24 23:41:39

试试 u8glib

mingzhi080218 发表于 2016-4-24 23:49:35

davidce 发表于 2016-4-24 23:41 static/image/common/back.gif
试试 u8glib

之前试过u8glib,里面有1351的彩色OLED,但好像不太支持SSD1331的屏,尝试改库文件但失败了。Adafruit_SSD1331的库也是前不久刚找到的才顺利点亮了屏幕。

wwwymq 发表于 2016-4-24 23:57:48

真是有钱人:o

mingzhi080218 发表于 2016-4-25 00:57:00

wwwymq 发表于 2016-4-24 23:57 static/image/common/back.gif
真是有钱人

:o         

mingzhi080218 发表于 2016-4-25 08:28:43

发个代码试下,麻烦大神们帮我看下,谢谢!#define sclk 30
#define mosi 28
#define cs   26
#define rst24
#define dc   22

#define BLACK         0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN         0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE         0xFFFF
#define BROWN          0xBC40
#define GRAY            0x2222
#define PURPLE          0xf81f
#define GND 23
#define lightSnr A1
#define fireSnr 7
#define rotation A0
int redLed = 12;
int blueLed = 13;
int speaker = 5;
int i;
float pi = 3.1415926 ;
int counter=0;

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);

#include <DHT.h>
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht (DHTPIN, DHTTYPE);


void setup() {
pinMode(GND,OUTPUT);
pinMode(lightSnr,INPUT);
pinMode(fireSnr,INPUT);
pinMode(rotation,INPUT);
pinMode(blueLed,OUTPUT);
pinMode(speaker,OUTPUT);
digitalWrite(GND,LOW);
display.begin();
dht.begin();
display.fillScreen(BLACK);
display.setCursor(5, 25);
display.setTextColor(GREEN);
display.setTextSize(1);
display.println("Initializing...");
delay(200);
sensorCheck();
//uint16_t time = millis();
//time = millis() - time;
display.fillScreen(BLACK);
delay(1);
//Serial.begin(115200);
attachInterrupt(0,counterChange,FALLING);
attachInterrupt(1,counterDown,FALLING);
}

void loop() {
switch(counter){
    case 0:envConsole();
    delay(200);
    break;
    case 1:showTemperature();
    delay(200);
    break;
    case 2:drawRadarbg();
    delay(200);
    break;
    case 3:clearScreen();
    delay(200);
    break;
    //case 4:drawThermo();
    //delay(200);
    //break;
}
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void drawRadarbg() {
display.fillScreen(BLACK);
display.setCursor(65,1);
display.setTextSize(1);
display.setTextColor(PURPLE);
display.println("M3");
display.fillTriangle(81,4,85,0,85,8,0x6666);
display.fillTriangle(87,0,87,8,91,4,0x6666);
for(int r=0; r<32; r=r+7){
display.drawCircle(49,33, r, GREEN);
}
display.drawFastVLine(49,2,62,GREEN);
display.drawFastHLine(7,33,82,GREEN);
display.drawFastVLine(94,1,62,GREEN);
display.drawFastVLine(95,1,62,GREEN);
display.drawFastVLine(1,1,62,GREEN);
display.drawFastVLine(0,1,62,GREEN);
for(int y=1; y < 63; y+=5){
display.drawFastHLine(2,y,3, GREEN);
display.drawFastHLine(91,y,3, GREEN);
}
while(1){
   //display.drawPixel(display.width()/2, display.height()/2, GREEN);   
for(int c=0;c<120;c++){
   int scanx=27*sin((c*3.0)/180.0*pi);
   int scany=27*cos((c*3.0)/180.0*pi);
   display.drawLine(49,33,49+scanx,33-scany,0x6600);
   display.drawFastVLine(49,2,62,GREEN);
   display.drawFastHLine(7,33,82,GREEN);
   //delay(1);
   for(int r=0; r<32; r=r+7){
   display.drawCircle(49,33, r, GREEN);
   }
}
   display.fillCircle(49,33,27,BLACK);
    if(counter!=2) break;
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void sensorCheck(){
   int h = dht.readHumidity();
   int t = dht.readTemperature();
   int f = dht.readTemperature(true);
   if (isnan(dht.readHumidity()) || isnan(dht.readTemperature())){
   display.fillScreen(BLACK);
   display.setCursor(5, 30);
   display.setTextColor(WHITE);
   display.setTextSize(1);
   display.println("Failed to read!");
   delay(500);
   display.fillScreen(BLACK);
   return;
   }
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void drawDataLine(){
/*int valLight=map(analogRead(A1),0,1023,45,15);
for(int x=36;x<90;x++){
display.drawPixel(x,valLight,YELLOW);
*/
int valRot=map(analogRead(rotation),0,1023,0,5);
int light;
int temp;
int humi;
for(i=0;i<100;i++){
light= map(analogRead(A1),0,1023,45,15);
humi = map(dht.readHumidity(),0,100,45,15);
temp= map(dht.readTemperature(),0,100,45,15);
delay(1);
}
for(int x=36;x<88;x++) {
    display.drawLine(x,light,x+1,light,YELLOW);
    display.drawLine(x,temp-valRot,x+1,temp-valRot,RED);
    display.drawLine(x,humi-valRot,x+1,humi-valRot,CYAN);
    delay(10);
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void drawTempData(){
int h = dht.readHumidity();
int t = dht.readTemperature();
int f = dht.readTemperature(true);
int valLight=map(analogRead(lightSnr),0,1023,0.02,1500);
display.setTextSize(1);
display.setCursor(9,13);
display.setTextColor(WHITE,BLACK);
display.print(t);
display.setCursor(9,26);
display.setTextColor(WHITE,BLACK);
display.print(h);
display.setCursor(9,39);
display.setTextColor(WHITE,BLACK);
display.print(f);
display.setCursor(45,52);
display.setTextSize(0);
display.setTextColor(WHITE,BLACK);
display.print("L=");
display.print(valLight);
delay(500);
display.fillRect(69,52,21,7,BLACK);
display.setCursor(57,52);
display.setTextSize(0);
display.setTextColor(WHITE,BLACK);
display.print(valLight);
delay(50);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void clearData(){
for(int y=13; y<40; y=y+13){
display.fillRect(9,y,15,7,BLACK);
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void clearDataLine(){
display.fillRect(36,15,54,31 ,BLACK);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void drawRuler(){
    display.drawFastVLine(1,1,display.height()-2,GREEN);
    display.drawFastVLine(0,1,display.height()-2,GREEN);
    display.drawFastVLine(94,1,display.height()-2,GREEN);
    display.drawFastVLine(95,1,display.height()-2,GREEN);
    for(int y=1; y < 63; y+=5){
    display.drawFastHLine(91,y,3, GREEN);
    }
    for(int y=1; y < 63; y+=5){
    display.drawFastHLine(2,y,3, GREEN);
    }
}

void drawTittle(){
display.setCursor(16,1);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println("EDMS");
display.setCursor(65,1);
display.setTextSize(1);
display.setTextColor(PURPLE);
display.println("M1");
display.setTextSize(1);
display.setCursor(1,13);
display.setTextColor(WHITE,RED);
display.println("T");
display.setCursor(1,26);
display.setTextColor(WHITE,CYAN);
display.println("H");
display.setCursor(1,39);
display.setTextColor(WHITE,GREEN);
display.println("F");
   
display.setCursor(25,13);
display.setTextColor(WHITE);
display.drawPixel(23,12,WHITE);
display.println("C");
display.setCursor(25,26);
display.setTextColor(WHITE);
display.println("%");
display.setCursor(25,39);
display.setTextColor(WHITE);
display.drawPixel(23,38,WHITE);
display.println("F");
}

void drawHead(){
display.drawLine(0,10,96,10,0x6666);
display.drawLine(11,0,11,10,0x6666);
display.drawLine(31,10,31,96,0x6666);
display.fillTriangle(81,4,85,0,85,8,0x2222);
display.fillTriangle(87,0,87,8,91,4,0x6666);
display.fillCircle(4,4,2,RED);
delay(500);
display.fillCircle(4,4,2,BLUE);
}

void drawTab(){
display.drawRect(32,12,62,38,GRAY);
for(int y=14; y<48; y=y+4){
    display.drawFastHLine(32,y,3,GRAY);
    display.drawFastHLine(90,y,3,GRAY);
}
   for(int x=35; x<90; x=x+4){
    display.drawFastVLine(x,12,3,GRAY);
    display.drawFastVLine(x,46,3,GREEN);
}
display.drawFastHLine(32,48,62,GREEN);
display.drawLine(92,46,94,48,GREEN);
display.drawLine(92,50,94,48,GREEN);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void tempAlarm(){
display.fillTriangle(23,52,18,62,29,62,YELLOW);
display.setCursor(21,56);
display.setTextColor(WHITE);
display.print("H");
delay(1000);
display.fillTriangle(23,52,18,62,29,62,BLACK);
}

void fireAlarm(){
display.fillTriangle(23,52,18,62,29,62,RED);
display.setCursor(21,56);
display.setTextColor(WHITE);
display.print("F");
delay(1000);
display.fillTriangle(23,52,18,62,29,62,BLACK);
}

void gasAlarm(){
display.fillTriangle(23,52,18,62,29,62,BLUE);
display.setCursor(21,56);
display.setTextColor(WHITE);
display.print("G");
delay(1000);
display.fillTriangle(23,52,18,62,29,62,BLACK);
}

void envStatus1(){
   display.fillRoundRect(0,50,13,13,2,GREEN);
   //display.fillRect(0,57,28,7,PURPLE);
display.fillRoundRect(15,50,13,13,2,0x6666);
display.setCursor(19,53);
display.setTextColor(0xFFFF);
//display.setTextSize(2);
display.print("G");
delay(500);   
display.fillRect(15,50,13,13,BLACK);
}

void envStatus2(){
   display.fillRoundRect(0,50,13,13,2,RED);
   delay(1000);
   //display.fillRect(0,50,28,14,BLACK);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void envComfirm(){
int h = dht.readHumidity();
int t = dht.readTemperature();
int f = dht.readTemperature(true);
int fire=digitalRead(7);
delay(1);
if(fire==0){
   envStatus2();
   fireAlarm();
   Alarm();
}
if(t>17&& t<33&& fire==1){
envStatus1();
}
if(t>32){
   envStatus2();
   tempAlarm();
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void envConsole(){
display.fillScreen(BLACK);
drawTittle();
drawHead();
drawTab();
while(1){
//sensorCheck();
drawHead();
drawTempData();
drawDataLine();
envComfirm();
clearDataLine();
//drawDataLine();
//envComfirm();
//clearDataLine();
if(counter!=0) break;
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void clearScreen(){
display.fillScreen(BLACK);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void showTemperature(){
int h = dht.readHumidity();
int t = dht.readTemperature();
display.fillScreen(BLACK);
drawThermo();
display.setCursor(16,1);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println("TEMP");
display.setCursor(65,1);
display.setTextSize(1);
display.setTextColor(PURPLE);
display.println("M2");
display.fillTriangle(81,4,85,0,85,8,0x6666);
display.fillTriangle(87,0,87,8,91,4,0x6666);
display.drawLine(0,9,96,9,0xFFFF);
display.drawLine(0,37,68,37,0xFFFF);
while(1){
   //sensorCheck();
   statusLt();
   int h = dht.readHumidity();
   int t = dht.readTemperature();
   display.fillRect(81,24,3,50-t,BLACK);
   display.fillRect(81,74-t,3,t-24,YELLOW);
   delay(5);
   display.setCursor(0,11);
   display.setTextColor(BLUE);
   display.setTextSize(1);
   display.println("Humidity");
   display.setCursor(0,21);
   display.setTextColor(GREEN,BLACK);
   display.setTextSize(2);
   display.print(h);
   display.println(" %");
   display.setCursor(0,39);
   display.setTextColor(RED);
   display.setTextSize(1);
   display.println("Temperature");
   display.setCursor(0,49);
   display.setTextColor(YELLOW,BLACK);
   display.setTextSize(2);
   display.print(t);
   display.println(" C");
   if(counter!=1) break;
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void blink(){
while(1){
digitalWrite(blueLed,HIGH);
delay(200);
digitalWrite(blueLed,LOW);
delay(200);
if(counter!=4) break;
}
}

void Alarm(){
for(int i=0; i<100; i++){
   digitalWrite(speaker,HIGH);
   delay(3);
   digitalWrite(speaker,LOW);
   delay(3);   
   }
   delay(200);
for(int i=0; i<100; i++){
   digitalWrite(speaker,HIGH);
   delay(3);
   digitalWrite(speaker,LOW);
   delay(3);
   }
   delay(200);
for(int i=0; i<100; i++){
   digitalWrite(speaker,HIGH);
   delay(3);
   digitalWrite(speaker,LOW);
   delay(3);
}
}

void statusLt(){
display.fillCircle(4,4,2,RED);
delay(500);
display.fillCircle(4,4,2,GREEN);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void counterChange(){
counter++;
if(counter>3) counter=0;
}
void counterDown(){
counter--;
if(counter<0) counter=0;
}

void drawThermo(){
display.drawCircle(82,56,5,0x2222);
display.drawRoundRect(80,19,5,35,2,0x2222);
display.fillCircle(82,56,3,YELLOW);
display.fillRect(81,24,3,30,YELLOW);
for(int y=51;y>21;y=y-3){
display.drawFastHLine(78,y,2,0x2222);
display.drawFastHLine(85,y,2,0x2222);
}
}

老胖熊 发表于 2016-4-25 11:28:21

个人观点,仅供参考:
1、DHT11精度确实不高,如要高精度的,可能就得换。
2、屏幕刷新的问题,我觉得是否可以试试用背景色画原来的图形,然后画新图形,不用整屏清屏。
3、按键要加防抖,硬软都行。最简单的,在按键上并一个104电容,也可以用软件去抖。即便你买很高级的按键,用久了可能也会抖。

mingzhi080218 发表于 2016-4-25 11:45:13

老胖熊 发表于 2016-4-25 11:28 static/image/common/back.gif
个人观点,仅供参考:
1、DHT11精度确实不高,如要高精度的,可能就得换。
2、屏幕刷新的问题,我觉得是否 ...

谢谢朋友!
1.考虑换DHT22试下。
2.此前已用朋友说的办法改成了现在的代码,数字刷新的问题基本能解决,但现仍有新问题出现,如果前一个数据位数后者,那么在更新数据时会出现托尾现象,比如前数据显示为26 C,如温度是两位数没有问题,若是突然温度降到一位数就会显示为6 CC。这个问题有点烦人,当然中断重启后可刷屏。实心图形的重新显示也就没办法整了。
3.应该是已经加 了104电阻的,但可能是在板上的传感器和其他元件太多的原因造成的吧。最大原因还是程序不够稳定,继续研究。
谢谢支持!:)

mingzhi080218 发表于 2016-4-25 12:05:51

老胖熊 发表于 2016-4-25 11:28 static/image/common/back.gif
个人观点,仅供参考:
1、DHT11精度确实不高,如要高精度的,可能就得换。
2、屏幕刷新的问题,我觉得是否 ...

不好意思,朋友,我搞错了,还没有加104电容,过些日子再试试看。

davidce 发表于 2016-4-25 12:16:55

mingzhi080218 发表于 2016-4-24 23:49 static/image/common/back.gif
之前试过u8glib,里面有1351的彩色OLED,但好像不太支持SSD1331的屏,尝试改库文件但失败了。Adafruit_SS ...

http://www.geek-workshop.com/thread-4998-1-1.html这个的屏幕也是ssd1331的芯片

老胖熊 发表于 2016-4-25 14:38:09

mingzhi080218 发表于 2016-4-25 12:05 static/image/common/back.gif
不好意思,朋友,我搞错了,还没有加104电容,过些日子再试试看。

26C变成6C会显示成6CC是有可能的,我觉得是因为刷新的时候没有覆盖掉原来的显示信息造成的。

我的意思是,比如,黑底白字,那么在显示6C之前,先用黑底黑字显示一下26C,然后再用黑底白字显示6C。这样,刷新的只是局部,不是全屏,可以一定程度避免闪屏。实心图形比如实心圆,也许可以考虑用方形区域覆盖实心圆,然后再画新图形,我觉得画方应该比画圆快。

加104电容应该挺管用的,我之前做过个类似的东西,开始测试的时候没加,有时候有抖动,按一次键会翻2次屏或者更多,加了104没出现过。软件去抖也可以,但是我觉得这种小mcu,能在代码上省点是点吧,毕竟处理能力有限。

mingzhi080218 发表于 2016-4-25 15:10:53

老胖熊 发表于 2016-4-25 14:38 static/image/common/back.gif
26C变成6C会显示成6CC是有可能的,我觉得是因为刷新的时候没有覆盖掉原来的显示信息造成的。

我的意思 ...

用黑底黑字应该是个不错的方法。我回去再试试。

mingzhi080218 发表于 2016-4-25 15:14:25

老胖熊 发表于 2016-4-25 14:38 static/image/common/back.gif
26C变成6C会显示成6CC是有可能的,我觉得是因为刷新的时候没有覆盖掉原来的显示信息造成的。

我的意思 ...

实心图形我已经在用朋友说的方法做了,比如第一屏的曲线图我就是用局部刷新的,虽然效果不是太好,但总是一个进步。雷达图我也是用一个实心圆来局部刷的。

mingzhi080218 发表于 2016-4-25 15:48:09

davidce 发表于 2016-4-25 12:16 static/image/common/back.gif
http://www.geek-workshop.com/thread-4998-1-1.html这个的屏幕也是ssd1331的芯片

谢谢指导!我先学习一下。
页: [1] 2
查看完整版本: 星期天在家弄了个SSD1331彩色OLED的小程序