
使用 Johnny-Five 的 Led.Digits 打造七段数码管数字时钟【免费下载链接】johnny-fiveJavaScript Robotics and IoT programming framework, developed at Bocoup.项目地址: https://gitcode.com/gh_mirrors/jo/johnny-five导读本文围绕 Johnny-FiveJavaScript Robotics and IoT 编程框架官方示例文档 docs/led-digits-clock.md 展开讲解如何利用Led.Digits驱动七段数码管7 Segment Digits在 Arduino、Intel Galileo Gen 2 等平台上实现一个每秒刷新的数字时钟。读完本文你将掌握Led.Digits的初始化方式、print()与digit()的底层工作机制、时间字符串的格式化技巧以及如何将同一段代码移植到不同控制器平台。示例概述一块会走的数字钟原文档给出了一个非常直观的示例使用七段数码管和 Intel Galileo Gen 2 打造一台时钟并且明确指出该示例可以轻松移植到任何 Johnny-Five 支持的平台例如 Arduino Uno。核心思路如下通过Led.Digits封装数码管硬件指定data、cs、clock三个引脚在board.on(ready)之后用setInterval每秒调用一次digits.print(time())time()函数借助 moment.js 生成形如02.25.54 P的格式化字符串并做一次正则替换得到适合单字母上下午meridiem的显示内容。在仓库中该示例存在三个版本可直接对照阅读eg/led-digits-clock.js默认 Arduino 平台版本eg/led-digits-clock-arduino.js与默认版本等价eg/led-digits-clock-galileo.js使用galileo-io作为 IO 层的 Galileo 版本。运行 Galileo 版本的方式与文档一致node eg/led-digits-clock-galileo.js运行普通 Arduino 版本则执行node eg/led-digits-clock.js接线图与硬件准备原文档提供了两种接线的 Fritzing 图均以仓库根目录为起点Galileo 接线图docs/breadboard/led-digits-clock-galileo.png对应 Fritzing 源文件 docs/breadboard/led-digits-clock-galileo.fzzArduino 接线图docs/breadboard/led-digits-clock-arduino.png对应 Fritzing 源文件 docs/breadboard/led-digits-clock-arduino.fzz。接线要点对应源码中的引脚配置数码管/驱动板的data、cs、clock三根信号线分别接到控制器的 2、3、4 号数字引脚本例配置公共端与电源按驱动板手册连接。仓库中还有基于 HT16K33 等 I2C 控制器的变体接线图如 docs/breadboard/led-digits-clock-HT16K33.png 和 docs/breadboard/led-digits-clock-dual.png可作为后续移植参考。完整代码与逐段讲解const moment require(moment); const { Board, Led } require(johnny-five); const Galileo require(galileo-io); const board new Board({ io: new Galileo() }); board.on(ready, () { var digits new Led.Digits({ pins: { data: 2, cs: 3, clock: 4, } }); setInterval(() digits.print(time()), 1000); }); function time() { /* The desired display looks something like these examples: 02.25.54 P 12.30.00 A moment doesnt have an option for a single letter meridiem (nor should it, that would be silly), so we need to manipulate the string a bit to so that it the string matches our desired display. */ return moment().format(hh.mm.ssA) .replace(/([AP])M/, $1); }1. 依赖与平台抽象const moment require(moment); const { Board, Led } require(johnny-five); const Galileo require(galileo-io);moment时间格式化库负责生成hh.mm.ssA形式的时间字符串johnny-five提供Board板卡抽象与LedLED 家族含Led.Digitsgalileo-ioGalileo 平台的 IO 适配层。若使用 Arduino则省略这一行直接new Board()即可见 eg/led-digits-clock-arduino.js。这种Board io 注入的结构正是 Johnny-Five 的平台可移植性来源代码逻辑不变只换 IO 层就能换硬件平台。2. 初始化数码管const digits new Led.Digits({ pins: { data: 2, cs: 3, clock: 4, } });Led.Digits是 lib/led/digits.js 中定义的一个极简类它继承自LedControl并强制options.isMatrix falseclass Digits extends LedControl { constructor(options) { options.isMatrix false; super(options); } static get CHARS() { return LedControl.DIGIT_CHARS; } }LedControl见 lib/led/ledcontrol.js支持两种控制器默认控制器MAX7219/MAX7221 类 SPI 驱动通过pins指定data、clock、cschip select也接受别名latch三个数字引脚。源码中初始化时会把这几个引脚全部设为OUTPUT模式见 lib/led/ledcontrol.js并按 MAX7219 的寄存器顺序发送BRIGHTNESS、SCANLIMIT、SHUTDOWN、DISPLAYTEST等配置指令HT16K33 控制器I2C 驱动通过address/addresses与dims配置适用于带 I2C 接口的数码管背板。pins既可以是对象{ data, clock, cs }也可以是数组[data, clock, cs]。其它可用选项还包括devices级联的驱动芯片数量、digits每块芯片的位数默认 8、colon设备是否内置冒号等。3. 每秒刷新一次setInterval(() digits.print(time()), 1000);每 1000ms 生成一次当前时间字符串并调用digits.print()。print()是LedControl的核心显示方法见 lib/led/ledcontrol.js它会用正则/([0-9A-Za-z][.]|[0-9A-Za-z:]|[\s])/g把字符串拆成字符单元支持带小数点字符、冒号、空白然后逐个调用digit()写入对应位置。若设备配置了colon: trueprint()还会在超过两个字符且第 3 个字符不是:或空格时自动插入空格占位让内置冒号的数码管更自然地居中显示。digit()见 lib/led/ledcontrol.js则负责把单个字符映射成段码优先查LedControl.DIGIT_CHARS字模表查不到时回退为Math.abs(Number(character))若字符后带.则与小数点段码0x80做按位或。4. 时间格式化与字符串处理return moment().format(hh.mm.ssA) .replace(/([AP])M/, $1);moment().format(hh.mm.ssA)输出 12 小时制时间如02.25.54PM。其中hh是 12 小时制01-12mm是分钟ss是秒A是 AM/PM 大写字母.replace(/([AP])M/, $1)把AM/PM压缩成单个字母A/P并在前面补一个空格使最终显示为02.25.54 P/12.30.00 A与七段数码管的显示习惯一致。小数点在这里起到分隔时、分、秒的作用., 段码为0x80这正是print()正则允许数字 小数点单元的原因。显示字模与字符支持Led.Digits.CHARS暴露了完整的数字字模表见 lib/led/led-chars.js它是LedControl.DIGIT_CHARS的静态别名支持数字0–9例如8: 0x7F全段点亮标点与分隔符空格0x00、小数点.0x80、冒号:0xFF、感叹号!0xB0大小写字母A–Z、a–z七段近似显示。如果你要显示自定义字符可以基于这张表扩展并把对应的 8 位段码直接传给digit(addr, position, chr)或直接传数字段码。移植到其它平台与控制器原文档强调这个示例可以轻松移植到任何其它受支持平台移植路径有两种更换 IO 层同一块数码管Galileo 用new Board({ io: new Galileo() })Arduino 用new Board()Raspberry Pi 可换成raspi-ioTessel 可换成tessel-io等业务代码不变更换驱动控制器同一套代码若数码管背板是 HT16K33I2C将pins换成address如0x70与dims其余print()/digit()调用方式一致该控制器的初始化、blink、brightness、clear等实现在 lib/led/ledcontrol.js 的Controllers.HT16K33中可据此了解 I2C 版本的行为差异。常见问题与注意事项必须等board.on(ready)再操作所有 IO 初始化都在 ready 事件之后进行否则引脚与控制器尚未就绪字符数量不要超过位数默认digits: 8本示例显示 8 个字符hh.mm.ss P恰好 8 个单元超出位数的字符会被忽略time()始终返回固定长度字符串moment().format(hh.mm.ssA)中hh/mm/ss均会补零保证 12 小时制下字符串长度稳定避免因数字位数变化导致显示错位SPI 引脚需要支持数字输出data、clock、cs必须使用数字引脚且注意电平与驱动板兼容。深入阅读数码管实现类lib/led/digits.js底层控制器MAX7219/HT16K33 双控制器实现lib/led/ledcontrol.js字模表含数字、冒号、小数点与字母lib/led/led-chars.js示例源码eg/led-digits-clock.js、eg/led-digits-clock-galileo.js相关教程文档docs/led-digits-clock-dual.md双模块时钟、docs/led-digits-clock-HT16K33.mdHT16K33 版结合本文的源码剖析你可以在任意 Johnny-Five 支持的平台上快速复现这台数码管时钟并将Led.Digits的print()能力扩展到倒计时器、秒表、计数器等更多场景。【免费下载链接】johnny-fiveJavaScript Robotics and IoT programming framework, developed at Bocoup.项目地址: https://gitcode.com/gh_mirrors/jo/johnny-five创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考