科技发展如此精尖的现代社会,还会有多少人记得“漂流瓶”这个东西呢?就算有人知道,现在的科技让漂流瓶也变成了虚拟的产物,残存在微信、QQ等各种社交网络中。在这个信息浮躁的世界,你有没有想过向海里丢一个真正的漂流瓶来倾诉自己的苦恼呢?
如果你真的去丢瓶子了,当瓶子飘走的时候你会不会后悔写在瓶子里的话呢?今天硬创邦的DIY教学就是教大家自制一个电子漂流瓶,有了这个电子漂流瓶后你就再也不用困扰这个问题啦!你可以随时发信息来更新你写下的话,有趣吧!
闲话不多说,教程开始。
这个项目主要运用了LinkIt One开发板而研发,在MediaTek的社区上,大多数的项目都是没有外壳的,甚至像用于户外的气象站这样的项目也没有,所以我要展示一个简易的现成的(取材于厨房)的防水的外壳。
大概的主要部件如下:
· 蓄电池供电
· 太阳能充电
· 放电或者充电状态以一行16x2的字符显示在液晶屏幕上
· 可以接收短信
· 信息可以滚动在屏幕上
我原本打算设计一款独立的、太阳能的、可以连接WiFi的漂流瓶,这样人们就可以在网上相互联系、下载资料或者相互留言,但是目前LinkIt One还不支持允许WiFi接入模式。所以我接下来想做一个像商店里做的那种蓝牙,当你进入商店你就可以接收信息(蓝牙营销),但目前应用界面程序好像还不允许……
1、Linkit One开发板
联发科的Linkit One是一款非常酷的兼容Arduino 的开发平台,你可以通过全球移动通讯系统接收短信,也可以给电池充电。
2、一张SIM卡
一张交过费并且可以接收短信的SIM卡,最好没有PIN码。
3、太阳能电池板
我从废旧的仪器上拿来了3个大约1W输出量的细长的8-10V的太阳能板,如果你不怕等快递的话,在Aliexpress网站上也能轻松买到。
4.电源转换器
我选用了Power Trends PT78ST105S这款,规格如下:
输入电压:9-38V
输出电压:5V
输出电流:1.5A
5、宽胶带
我用宽胶带把三个太阳能板粘成可折叠的组合,再把各种模块粘到太阳能板的背面。折叠之后看起来相当整齐。
6、一个瓶子
最好用腌制果酱的广口瓶,但是我没找到,所以用了一个1.5升的弹簧瓶。
简单的办法
如果你不想自己设计电路,可以去Aliexpress这样的网站买一个太阳能手机充电器,付完钱等两个月就ok了。
复杂的办法
这有一个用太阳能给你的LinkIt One充电的深入教程,要是想了解更多的话可以阅读一下(全英文哦,学渣慎入)。
连接电池板
把电池板摆成三角管状(像Toblerone三角巧克力,具体长啥样自行度娘),这个问题有点复杂,但是你掌握以下几点即可:
1.一组串联电池中的输出电流大小取决于电量最小的电池产生电流的能力。
2.照明度一定时,输出电压是恒定的。
如果电池是串联的,其中一个变暗,总电流会减小,如果是并联的,能吸收光能的电池就可以无限的输出电能。
选择5V的转换器
LinkIt One开发板有一个内置充电器,通过USB端口就可以给这个内置充电器稳定地输入5V的电压。太阳能电池板的输出电压随着吸收光能的变化在5V附近轻微浮动,所以我们需要一个开关型稳压器降低电压。
转换器有许多种,你只需要选一个满足下列要求的就可以了。
输入电压(电池板输入端):
确保电池板的输出电压在开关型稳压器的输入电压范围内。
输出电压(连到LinkIt One端)
5V(不能多不能少正正好好)
输出电流
稳压器一定要能负载通过的电流,看一下电池板的额定电流(在电源上可以看见),这是最大允许的输入电流。不计无用功,输出电流=输入电流*(输入电压/输出电压)。
稳压器示例(1)
我手边有一个型号是Power Trends PT78ST105S的稳压器,规格如下:
输入电压:9-38V
输出电压:5V
输出电流:1.5A
稳压器示例(2)
我把两个8V的电池串联起来组成了一个最小输入电压为14V的电池。
输入电压:14-28V
输出电压:5V
输出电流:500mA
连接5V的转换器
需要一个微型USB连接器,我从废弃的电话充电器上取下来一个。
连接步骤如下:
电池板的正极连到稳压器的VIN端
电池板的负极连到稳压器的GND端
稳压器的输出电压端连接USB连接器的+5V端
稳压器的GND端连接到USB连接器的GND端
连接
我从旧家电上拿到了一个16x2的液晶显示屏,如果你有16x4的或者任何带有HD44780芯片的类似的显示屏都可以。
下表列出了所有接口的作用。
如果显示器有背光源,那么这就是在15和15端口间的发光二极管。这种显示器比较费电。
想了解更多关于16x2显示屏的信息请点击连接Adafruit's well documented articles。
测试
充上电源连接好各端口之后,显示屏上应该就可以看到信号了,如果没有的话一定是哪里出错了,检查一下各连接处,调节对比电阻器,把端口3直接连到GND上可以设置最大对比度。
现在让我们开始写代码控制显示器吧。
注意:关于LiquidCrystal库
就在写这个教程的时候,我用的这个1.6.5版本Arduino的LinkIt One硬盘驱动器的LiquidCrystal库崩溃了,如何修补LiquidCrystal文档请参照Instructable。
简介:
我想你应该能让LinkIt One 和Arduino 硬盘驱动器同时运行了,如果没有请点击这里。
我已经把最终版的代码写在这里了,特别描述了其中比较重要的部分,这或许会让你更好的理解这个程序 。
导库
首先导入会用到的各种库。
#include <LGSM.h>
#include <LiquidCrystal.h>
#include <LBattery.h>
定义变量
接下来我们定义整个程序中会用到的总体变量,大部分变量都会定义为“进程名[x]”,也就是一系列X字符,可以用来储存文本或状态信息。
//these variables are for the sms
char smsContent[160];
int smsLength = 0;
char smsSender[20];
boolean newMessage = LOW;
//variables for battery status
char statusMessage[16];
// initialize the LCD library with the numbers of the interface pins
// lcd(RS, Enable, DataBus4, DataBus5, DataBus6, DataBus7)
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
int scrollInterval = 500;
unsigned long lastUpdate = 0;
int msgStartChar = 0;
int lcdStartChar = 0;
设置方法
主板导入的时候这个函数就会运行。
void setup() {
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
waitForSim(); //wait for simcard to be active
Serial.begin(9600); //start the serial port
}
等待SIM卡准备就绪方法
如果SIM卡没有初始化的话程序还不能正常运行,所以你只能等SIM卡准备就绪,这个时候你可以在界面上打出小点确保设备还是完好的。
void waitForSim() {
Serial.print("waiting for sim");
while (!LSMS.ready())
{
delay(250);
Serial.print('.');
}
Serial.println("Sim Ready");
}
接收短信方法
当收到新消息时,这个函数就可以自动查看,一次读取一个字符,并储存在缓冲箱内,函数返回高档(true/1),没有新消息时返回低档(false/0)。收到新消息时,“新消息”boolean设置成True。读取信息之后信息会被删除。
boolean receiveSMS() {
//this function will store a new sms in the buffers
//or return false if there is no new sms
int v;
if (LSMS.ready() && LSMS.available()) // Check if there is new SMS
{
Serial.println("There is new message.");
newMessage = HIGH;
LSMS.remoteNumber(smsSender, 20); // store sender in buffer
smsLength = 0; //storing a new sms
while (true)
{
v = LSMS.read();
if (v < 0)
break;
smsContent[smsLength] = v;
smsLength++;
}
smsContent[smsLength] = '\0';
smsLength++;
LSMS.flush(); // delete message
return HIGH;
}
else {
return LOW;
}
}
充电状态方法
这个函数由16个字符的文本组成。充电状态用1表示,未充电状态用0表示。剩余电量用0,33,66,100表示,电池的电流量水平决定了剩余电量。用sprintf函数把前两个函数转化成一行文本的格式,在此文本中,储存的状态信息字符用于下面的更新显示函数中。
void chargeStatus() {
if(LBattery.isCharging()) {
sprintf(statusMessage,"%3d%% charging", LBattery.level() );
}
else {
sprintf(statusMessage,"%3d%% charged", LBattery.level() );
}
}
更新显示函数
前面形成的文本内容都要发送到液晶显示屏上,通过显示屏我们才能直观的感受到信息以及查看评论。首先要说的是计数器的作用,显示屏一更新(以毫秒计,Arduino millis函数提供)它就会记录下来,过一会儿可以再次更新。
储存下面两个变量可以使第二行上的信息滚动:
msgStartChar
这个变量会储存先输入的信息字符(因为也不能把160个字全都输在16个字符行里去)
lcdStartChar
这个变量储存显示屏上出现的信息,从右侧开始滚动。
从右侧开始(位置15)减少lcdStartChar,一直到信息从第一个字符开始(位置0)显示的内容就可以更新了,并且可以使信息滚动到左边。信息滚动到最左边以后,依次增加msgStartChar,就又重新滚动回屏幕了。
void updateDisplay() {
//this function will scroll the message on one line and display battery status on the other
unsigned long currentMillis = millis();
if (currentMillis - lastUpdate > scrollInterval) {
lastUpdate = currentMillis;
//get battery status
chargeStatus();
lcd.clear(); //first we clear the whole lcd
lcd.setCursor(0, 0); //set cursor to first line
lcd.print(statusMessage);
//print sms on the 2nd line
if (newMessage == HIGH) {
msgStartChar = 0; //goto first line of new message
lcdStartChar = 15;
newMessage = LOW; //message dealt with
}
lcdStartChar = max(0,lcdStartChar - 1); //move one char along on the message (for scrolling)
lcd.setCursor(0, 1); //set cursor to bottom line
for (int j=0; j<= 15; j++) {
if (j < lcdStartChar) {
lcd.print(" ");
}
else if ((msgStartChar+(j-lcdStartChar)) < (smsLength-1)) {
lcd.print(smsContent[msgStartChar+(j-lcdStartChar)]);
}
else {
lcd.print(" ");
}
}
if (lcdStartChar <= 0) {
msgStartChar++; //move message to the left
}
if (msgStartChar >= smsLength) {
Serial.println("End of message");
//we have reached the end of the message, go back to the start
lcdStartChar = 15;
msgStartChar = 0;
}
}
}
这一步一点也不麻烦,只需要你选的电池板、液晶显示屏和那个大瓶子。看看我的照片,我用胶布把三个电池板绑成三角管的形状,便于折叠。
这个三角形的第四条边,好吧,这已经不是三角形了,这个第四条边是一块轻质木头,在中间凿一个四边形用来放显示屏。
同样,用胶布把这个木片粘好。没连接起来的那边用胶布粘一块小磁铁,这样就方便打开和折叠了。看,就是这么简单!
圣诞节来了,硬创邦微信公众号要给技术宅单身汪汪们发福利啦!12月25日将抽三名幸运用户,每人送Arduino开发板一块!
雷锋网在未来三个月内选一个合适的时间,在北上深选择一个地点,举办创马“火星救援”专场!详情可点此处了解。
此外还可加入全球创客马拉松主群(群号:259592983),参与我们的互动讨论~