LCD1602A 显示器 显示时钟和IP(显示所有连接) 树莓派3

LCD1602A 显示器和树莓派通信方式为i2c形式的,i2c是一种串行总线。有串行数据线(SDA),串行时钟线(SCL),电源和接地与设备连接。文章内容为:设备演示图,设备接线图,相关代码。

硬件:树莓派3 LCD1602A显示器 网线 树莓电源。DIY了一下,将显示器放到了外壳的上盖面了。

LCD1602A

显示器与pi3间使用i2c通信

LCD1602A

设备接线:

LCD1602A

ip显示方式 e为有线地址:

IP

w为无线显示 同时连接时循环两秒显示:

IP

未连接网络

IP

pi3与电脑间网线直连,将电脑IP地址改到与pi3同一网段也可以使用vnc

源代码来自GitHub,代码c++经过简单修改而来

源GitHub链接

根据源链接说明,编译文件后,可执行文件在bin目录,根据格式执行就可以。

1
2
3
4
$ cd ipClock/src
$ make install
$ ipClock -a27 -f1
$ killall ipClock

Raspberry i2c命令:

https://tl8517.com/raspberrypi-command

cron 选择编辑器及开机启动配置,不能开机启动:

https://tl8517.com/cron

下面是我修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//修改后的
#include "main.h"
static unsigned int lcdAddress;
static int tries = 5;
static char dateFormat = '1';
static volatile int lcdHandle;
int marquee = 0;
#define lcdWidth 16
#define maxMessageSize 128
char msg[1024];
bool usage() {
fprintf(stderr, "usage: lcdClock [-d] [-a 00-FF] [-p 0-40] [-f n] [-s speed] [-m motd]\n");
fprintf(stderr, "a = hexadecimal i2c address ($gpio i2cd)\n");
fprintf(stderr, "f = clock format\n");
fprintf(stderr, " 1 - Weekday Month Date HH24:MM\n");
fprintf(stderr, " 2 - Weekday Date HH:MM AM/PM\n");
return false;
}
bool setup() {
if (int ret = wiringPiSetup()) {
fprintf(stderr, "Wiring Pi setup failed, ret=%d\n", ret);
return false;
}
int seed;
FILE *fp;
fp = fopen("/dev/urandom", "r");
fread(&seed, sizeof(seed), 1, fp);
fclose(fp);
srand(seed);
// the following statements setup the proper input or output for their respective
// inputs or outputs
lcdHandle=lcdSetup(lcdAddress);
if (lcdHandle < 0) {
fprintf(stderr, "lcdInit failed\n");
return false;
}
return true;
}
bool commandLineOptions(int argc, char **argv) {
int c, index;
if (argc < 2) {
return usage();
}
while ((c = getopt(argc, argv, "a:f:")) != -1)
switch (c) {
case 'a':
if (strcmp(optarg, "0x") == 0) {
sscanf(&optarg[2], "%x", &lcdAddress);
} else {
sscanf(optarg, "%x", &lcdAddress);
}
break;
case 'f':
dateFormat = optarg[0];
break;
case '?':
if (optopt == 'a' optopt == 'p' optopt == 'f' optopt == 'm' optopt == 's')
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf(stderr, "Unknown option character \\x%x.\n", optopt);
return usage();
default:
abort();
}
//for (index = optind; index < argc; index++)
//printf("Non-option argument %s\n", argv[index]);
return true;
}
static uint8_t sizecvt(const int read)
{
/* digitalRead() and friends from wiringpi are defined as returning a value
< 256. However, they are returned as int() types. This is a safety function */
if (read > 255 read < 0)
{
printf("Invalid data from wiringPi library\n");
exit(EXIT_FAILURE);
}
return (uint8_t)read;
}
void updateClock() {
auto now = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(now);
char vtime[64];
switch (dateFormat) {
case '2':std::strftime(vtime, 64, "%a %e %I:%M %p", std::localtime(&end_time));
break;
default:
if (std::localtime(&end_time)->tm_mday < 10) {
char xtime[64];
std::strftime(xtime, 64, "%a %b %%d %H:%M", std::localtime(&end_time));
sprintf(vtime, xtime, std::localtime(&end_time)->tm_mday);
}
else {
std::strftime(vtime, 64, "%a %b %e %H:%M", std::localtime(&end_time));
}
}
lcdPosition(lcdHandle, 0, 0); //Position cursor on the first line in the first column
if (strlen(vtime) > 16) {
vtime[16] = 0;
}
lcdPuts(lcdHandle, vtime); //Print the text on the LCD at the current cursor postion
FILE *input;
char wlan[256]="";
char eth0[256]="";
lcdPosition(lcdHandle, 0, 1);
input = popen("/sbin/ifconfig eth0 awk '{if ($1==\"inet\") printf(\"%s\", $2)}'", "r");
fgets(eth0, 255, input);
fclose(input);
lcdPosition(lcdHandle, 0, 1);
input = popen("/sbin/ifconfig wlan0 awk '{if ($1==\"inet\") printf(\"%s\", $2)}'", "r");
fgets(wlan, 255, input);
fclose(input);
if (strlen(eth0) > 0 & strlen(wlan) > 0){
lcdPrintf(lcdHandle, "w%s\n", wlan);
sleep(2);
lcdPuts(lcdHandle, vtime); //Print the text on the LCD at the current cursor postion
lcdPrintf(lcdHandle, "e%s\n", eth0);
sleep(2);
} else {
if (strlen(eth0) > 0){
lcdPrintf(lcdHandle, "e%s\n", eth0);
sleep(2);
}else{
if (strlen(wlan) > 0){
lcdPrintf(lcdHandle, "w%s\n",wlan );
sleep(2);
}else{
lcdPrintf(lcdHandle,"*No Connection*\n");
}
}
}
}
int main(int argc, char **argv)
{
int i;
if (!commandLineOptions(argc, argv)) {
return 1;
}
if (!setup()) {
printf("setup failed\n");
return 1;
}
printf("Press ^c to exit IP Clock\n");
while (1) {
updateClock();
//delay(1000);
}
return 0;
}

树莓派3更多模块请点击链接:

从入门到放弃的学习RASPBERRYPI