Added a 14 segment LED example, driven by the HT16K33 (#219)
No fritzing parts available for the device so no diagrams
This commit is contained in:
@@ -86,6 +86,7 @@ App|Description
|
||||
[ssd1306_i2c](i2c/ssd1306_i2c) | Convert and display a bitmap on a 128x32 or 128x64 SSD1306-driven OLED display
|
||||
[pa1010d_i2c](i2c/pa1010d_i2c) | Read GPS location data, parse and display data via I2C.
|
||||
[pcf8523_i2c](i2c/pcf8523_i2c) | Read time and date values from a real time clock. Set current time and alarms on it.
|
||||
[ht16k33_i2c](i2c/ht16k33_i2c) | Drive a 4 digit 14 segment LED with an HT16K33.
|
||||
|
||||
### Interpolator
|
||||
|
||||
|
||||
@@ -10,4 +10,5 @@ if (NOT PICO_NO_HARDWARE)
|
||||
add_subdirectory(ssd1306_i2c)
|
||||
add_subdirectory(pa1010d_i2c)
|
||||
add_subdirectory(pcf8523_i2c)
|
||||
add_subdirectory(ht16k33_i2c)
|
||||
endif ()
|
||||
|
||||
12
i2c/ht16k33_i2c/CMakeLists.txt
Normal file
12
i2c/ht16k33_i2c/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
add_executable(ht16k33_i2c
|
||||
ht16k33_i2c.c
|
||||
)
|
||||
|
||||
# pull in common dependencies and additional i2c hardware support
|
||||
target_link_libraries(ht16k33_i2c pico_stdlib hardware_i2c)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(ht16k33_i2c)
|
||||
|
||||
# add url via pico_set_program_url
|
||||
example_auto_set_url(ht16k33_i2c)
|
||||
39
i2c/ht16k33_i2c/README.adoc
Normal file
39
i2c/ht16k33_i2c/README.adoc
Normal file
@@ -0,0 +1,39 @@
|
||||
= Attaching a 4 digit 14 segment LED driven by the HT15k33 via I2C
|
||||
|
||||
This example code shows how to interface the Raspberry Pi Pico to one HT16K33 driven 4 digit 14 segment LED. The device used for development
|
||||
uses VCC at 5v, but also allows the I2C voltage to be selected by connecting the vi2c pin to the appropriate voltage, in the Pico case 3v3 as the
|
||||
GPIO pins are not 5v tolerant.
|
||||
|
||||
NOTE: Other manufacturers make very similar devices with very similar names (e.g. Vinka VK16K33)). These may or may not work!
|
||||
|
||||
== Wiring information
|
||||
|
||||
Wiring up the device requires 5 jumpers, to connect VCC (3.3v), GND, vi2c (3v3), SDA and SCL. The example here uses I2C port 0, which is assigned to GPIO 4 (SDA) and 5 (SCL) in software. Power is supplied from the 3.3V pin.
|
||||
|
||||
WARNING: Some displays of this type are 5v with no option to select 3v3 for the I2c. If you wish to use a 5v display you will need to use level shifters on the SDA and SCL lines to convert from the 3.3V used by the RP2040.
|
||||
|
||||
Connections on Raspberry Pi Pico board, other boards may vary.
|
||||
|
||||
GPIO 4 (pin 6)-> SDA on LED board
|
||||
GPIO 5 (pin 7)-> SCL on LED board
|
||||
GND (pin 38) -> GND on LED board
|
||||
5v (pin 40) -> VCC on LED board
|
||||
3.3v (pin 36) -> vi2c on LED board
|
||||
|
||||
== List of Files
|
||||
|
||||
CMakeLists.txt:: CMake file to incorporate the example in to the examples build tree.
|
||||
ht15k33_i2c.c:: The example code.
|
||||
|
||||
== Bill of Materials
|
||||
|
||||
.A list of materials required for the example
|
||||
[[ht15k33_i2c-bom-table]]
|
||||
[cols=3]
|
||||
|===
|
||||
| *Item* | *Quantity* | Details
|
||||
| Breadboard | 1 | generic part
|
||||
| Raspberry Pi Pico | 1 | https://www.raspberrypi.com/products/raspberry-pi-pico/
|
||||
| ht16k33 based LCD panel | 1 | generic part
|
||||
| M/M Jumper wires | 5 | generic part
|
||||
|===
|
||||
228
i2c/ht16k33_i2c/ht16k33_i2c.c
Normal file
228
i2c/ht16k33_i2c/ht16k33_i2c.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include "pico/binary_info.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* Example code to drive a 4 digit 14 segment LED backpack using a HT16K33 I2C
|
||||
driver chip
|
||||
|
||||
NOTE: The panel must be capable of being driven at 3.3v NOT 5v. The Pico
|
||||
GPIO (and therefore I2C) cannot be used at 5v. In development the particular
|
||||
device used allowed the PCB VCC to be 5v, but you can set the I2C voltage
|
||||
to 3.3v.
|
||||
|
||||
Connections on Raspberry Pi Pico board, other boards may vary.
|
||||
|
||||
GPIO 4 (pin 6)-> SDA on LED board
|
||||
GPIO 5 (pin 7)-> SCL on LED board
|
||||
GND (pin 38) -> GND on LED board
|
||||
5v (pin 40) -> VCC on LED board
|
||||
3.3v (pin 36) -> vi2c on LED board
|
||||
*/
|
||||
|
||||
// How many digits are on our display.
|
||||
#define NUM_DIGITS 4
|
||||
|
||||
// By default these display drivers are on bus address 0x70. Often there are
|
||||
// solder on options on the PCB of the backpack to set an address between
|
||||
// 0x70 and 0x77 to allow multiple devices to be used.
|
||||
const int I2C_addr = 0x70;
|
||||
|
||||
|
||||
// commands
|
||||
|
||||
|
||||
#define HT16K33_SYSTEM_STANDBY 0x20
|
||||
#define HT16K33_SYSTEM_RUN 0x21
|
||||
|
||||
#define HT16K33_SET_ROW_INT 0xA0
|
||||
|
||||
#define HT16K33_BRIGHTNESS 0xE0
|
||||
|
||||
// Display on/off/blink
|
||||
#define HT16K33_DISPLAY_SETUP 0x80
|
||||
// OR/clear these to display setup register
|
||||
#define HT16K33_DISPLAY_OFF 0x0
|
||||
#define HT16K33_DISPLAY_ON 0x1
|
||||
#define HT16K33_BLINK_2HZ 0x2
|
||||
#define HT16K33_BLINK_1HZ 0x4
|
||||
#define HT16K33_BLINK_0p5HZ 0x6
|
||||
|
||||
// Converts a character to the bit pattern needed to display the right segments.
|
||||
// These are pretty standard for 14segment LED's
|
||||
uint16_t char_to_pattern(char ch) {
|
||||
// Map, "A" to "Z"
|
||||
int16_t alpha[] = {
|
||||
0xF7,0x128F,0x39,0x120F,0xF9,0xF1,0xBD,0xF6,0x1209,0x1E,0x2470,0x38,0x536,0x2136,
|
||||
0x3F,0xF3,0x203F,0x20F3,0x18D,0x1201,0x3E,0xC30,0x2836,0x2D00,0x1500,0xC09
|
||||
};
|
||||
|
||||
// Map, "0" to "9"
|
||||
int16_t num[] = {
|
||||
0xC3F,0x406,0xDB,0x8F,0xE6,0xED,0xFD,0x1401,0xFF,0xE7
|
||||
};
|
||||
|
||||
if (isalpha(ch))
|
||||
return alpha[toupper(ch) - 'A'];
|
||||
|
||||
if (isdigit(ch))
|
||||
return num[ch - '0'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Quick helper function for single byte transfers */
|
||||
inline void i2c_write_byte(uint8_t val) {
|
||||
#ifdef i2c_default
|
||||
i2c_write_blocking(i2c_default, I2C_addr, &val, 1, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ht16k33_init() {
|
||||
i2c_write_byte(HT16K33_SYSTEM_RUN);
|
||||
i2c_write_byte(HT16K33_SET_ROW_INT);
|
||||
i2c_write_byte(HT16K33_DISPLAY_SETUP | HT16K33_DISPLAY_ON);
|
||||
}
|
||||
|
||||
// Send a specific binary value to the specified digit
|
||||
inline void ht16k33_display_set(int position, uint16_t bin) {
|
||||
uint8_t buf[3];
|
||||
buf[0] = position * 2;
|
||||
buf[1] = bin & 0xff;
|
||||
buf[2] = bin >> 8;
|
||||
i2c_write_blocking(i2c_default, I2C_addr, buf, count_of(buf), false);
|
||||
}
|
||||
|
||||
inline void ht16k33_display_char(int position, char ch) {
|
||||
ht16k33_display_set(position, char_to_pattern(ch));
|
||||
}
|
||||
|
||||
void ht16k33_display_string(char *str) {
|
||||
int digit = 0;
|
||||
while (*str && digit <= NUM_DIGITS) {
|
||||
ht16k33_display_char(digit++, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
void ht16k33_scroll_string(char *str, int interval_ms) {
|
||||
int l = strlen(str);
|
||||
|
||||
if (l <= NUM_DIGITS) {
|
||||
ht16k33_display_string(str);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < l - NUM_DIGITS + 1; i++) {
|
||||
ht16k33_display_string(&str[i]);
|
||||
sleep_ms(interval_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ht16k33_set_brightness(int bright) {
|
||||
i2c_write_byte(HT16K33_BRIGHTNESS | (bright <= 15 ? bright : 15));
|
||||
}
|
||||
|
||||
void ht16k33_set_blink(int blink) {
|
||||
int s = 0;
|
||||
switch (blink) {
|
||||
default: break;
|
||||
case 1: s = HT16K33_BLINK_2HZ; break;
|
||||
case 2: s = HT16K33_BLINK_1HZ; break;
|
||||
case 3: s = HT16K33_BLINK_0p5HZ; break;
|
||||
}
|
||||
|
||||
i2c_write_byte(HT16K33_DISPLAY_SETUP | HT16K33_DISPLAY_ON | s);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
stdio_init_all();
|
||||
|
||||
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
||||
#warning i2c/ht16k33_i2c example requires a board with I2C pins
|
||||
#else
|
||||
// This example will use I2C0 on the default SDA and SCL pins (4, 5 on a Pico)
|
||||
i2c_init(i2c_default, 100 * 1000);
|
||||
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
|
||||
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
|
||||
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
|
||||
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
|
||||
// Make the I2C pins available to picotool
|
||||
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
||||
|
||||
printf("Welcome to HT33k16!\n");
|
||||
|
||||
ht16k33_init();
|
||||
|
||||
ht16k33_display_set(0, 0);
|
||||
ht16k33_display_set(1, 0);
|
||||
ht16k33_display_set(2, 0);
|
||||
ht16k33_display_set(3, 0);
|
||||
|
||||
again:
|
||||
|
||||
ht16k33_scroll_string("Welcome to the Raspberry Pi Pico", 150);
|
||||
|
||||
// Do a speeding up propeller effort using the inner segments
|
||||
int bits[] = {0x40, 0x0100, 0x0200, 0x0400, 0x80, 0x2000, 0x1000, 0x0800};
|
||||
for (int j = 0;j < 10;j++) {
|
||||
for (int i = 0;i< count_of(bits); i++) {
|
||||
for (int digit = 0;digit <= NUM_DIGITS; digit++) {
|
||||
ht16k33_display_set(digit, bits[i]);
|
||||
}
|
||||
sleep_ms(155 - j*15);
|
||||
}
|
||||
}
|
||||
|
||||
char *strs[] = {
|
||||
"Help", "I am", "in a", "Pico", "and ", "Cant", "get ", "out "
|
||||
};
|
||||
|
||||
for (int i = 0; i < count_of(strs); i++) {
|
||||
ht16k33_display_string(strs[i]);
|
||||
sleep_ms(500);
|
||||
}
|
||||
|
||||
sleep_ms(1000);
|
||||
|
||||
// Test brightness and blinking
|
||||
|
||||
// Set all segments on all digits on
|
||||
ht16k33_display_set(0, 0xffff);
|
||||
ht16k33_display_set(1, 0xffff);
|
||||
ht16k33_display_set(2, 0xffff);
|
||||
ht16k33_display_set(3, 0xffff);
|
||||
|
||||
// Fade up and down
|
||||
for (int j=0;j<5;j++) {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
ht16k33_set_brightness(i);
|
||||
sleep_ms(30);
|
||||
}
|
||||
|
||||
for (int i = 14; i >=0; i--) {
|
||||
ht16k33_set_brightness(i);
|
||||
sleep_ms(30);
|
||||
}
|
||||
}
|
||||
|
||||
ht16k33_set_brightness(15);
|
||||
|
||||
ht16k33_set_blink(1); // 0 for no blink, 1 for 2Hz, 2 for 1Hz, 3 for 0.5Hz
|
||||
sleep_ms(5000);
|
||||
ht16k33_set_blink(0);
|
||||
|
||||
goto again;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user