Updates along with SDK1.3.0 release (#181)
Bug fixes and new examples Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: martin <admin@crossleys.biz> Co-authored-by: matiasilva <matias.silva@raspberrypi.com> Co-authored-by: Uri Shaked <uri@urishaked.com> Co-authored-by: Diego Solano <diegosolano@gmail.com> Co-authored-by: Andrew Scheller <andrew.scheller@raspberrypi.com> Co-authored-by: Adrian Hesketh <a-h@users.noreply.github.com> Co-authored-by: Emircan Gündoğdu <58917386+emircangun@users.noreply.github.com> Co-authored-by: Josef Wegner <80200012+josefwegner@users.noreply.github.com> Co-authored-by: pmarques-dev <72901351+pmarques-dev@users.noreply.github.com> Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: mjcross <mjcross@users.noreply.github.com> Co-authored-by: martin <admin@crossleys.biz>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
if (NOT PICO_NO_HARDWARE)
|
||||
add_subdirectory(hello_uart)
|
||||
add_subdirectory(lcd_uart)
|
||||
add_subdirectory(uart_advanced)
|
||||
endif ()
|
||||
|
||||
@@ -2,7 +2,7 @@ add_executable(hello_uart
|
||||
hello_uart.c
|
||||
)
|
||||
|
||||
# Pull in our pico_stdlib which pulls in commonly used features
|
||||
# pull in common dependencies
|
||||
target_link_libraries(hello_uart pico_stdlib)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
|
||||
17
uart/lcd_uart/CMakeLists.txt
Normal file
17
uart/lcd_uart/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
add_executable(lcd_uart
|
||||
lcd_uart.c
|
||||
)
|
||||
|
||||
# pull in common dependencies and additional uart hardware support
|
||||
target_link_libraries(lcd_uart pico_stdlib hardware_uart)
|
||||
|
||||
# enable usb output and uart output
|
||||
# modify here as required
|
||||
pico_enable_stdio_usb(lcd_uart 1)
|
||||
pico_enable_stdio_uart(lcd_uart 1)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(lcd_uart)
|
||||
|
||||
# add url via pico_set_program_url
|
||||
example_auto_set_url(lcd_uart)
|
||||
39
uart/lcd_uart/README.adoc
Normal file
39
uart/lcd_uart/README.adoc
Normal file
@@ -0,0 +1,39 @@
|
||||
= Attaching a 16x2 LCD via TTL
|
||||
|
||||
This example code shows how to interface the Raspberry Pi Pico to one of the very common 16x2 LCD character displays. Due to the large number of pins these displays use, they are commonly used with extra drivers or backpacks. In this example, we will use an Adafruit LCD display backpack, which supports communication over USB or TTL. A monochrome display with an RGB backlight is also used, but the backpack is compatible with monochrome backlight displays too. There is another example that uses I2C to control a 16x2 display.
|
||||
|
||||
The backpack processes a set of commands that are documented https://learn.adafruit.com/usb-plus-serial-backpack/command-reference[here] and preceded by the "special" byte 0xFE. The backpack does the ASCII character conversion and even supports custom character creation. In this example, we use the Pico's primary UART (uart0) to read characters from our computer and send them via the other UART (uart1) to print them onto the LCD. We also define a special startup sequence and vary the display's backlight color.
|
||||
|
||||
NOTE: You can change where stdio output goes (Pico's USB, uart0 or both) with CMake directives. The CMakeLists.txt file shows how to enable both.
|
||||
|
||||
== Wiring information
|
||||
|
||||
Wiring up the backpack to the Pico requires 3 jumpers, to connect VCC (3.3v), GND, TX. The example here uses both of the Pico's UARTs, one (uart0) for stdio and the other (uart1) for communication with the backpack. Pin 8 is used as the TX pin. Power is supplied from the 3.3V pin. To connect the backpack to the display, it is common practice to solder it onto the back of the display, or during the prototyping stage to use the same parallel lanes on a breadboard.
|
||||
|
||||
NOTE: While this display will work at 3.3V, it will be quite dim. Using a 5V source will make it brighter.
|
||||
|
||||
[[lcd_uart_wiring]]
|
||||
[pdfwidth=75%]
|
||||
.Wiring Diagram for LCD with TTL backpack.
|
||||
image::lcd_uart_bb.png[]
|
||||
|
||||
== List of Files
|
||||
|
||||
CMakeLists.txt:: CMake file to incorporate the example in to the examples build tree.
|
||||
lcd_uart.c:: The example code.
|
||||
|
||||
== Bill of Materials
|
||||
|
||||
.A list of materials required for the example
|
||||
[[lcd_uart-bom-table]]
|
||||
[cols=3]
|
||||
|===
|
||||
| *Item* | *Quantity* | Details
|
||||
| Breadboard | 1 | generic part
|
||||
| Raspberry Pi Pico | 1 | https://www.raspberrypi.com/products/raspberry-pi-pico/
|
||||
| 16x2 RGB LCD panel 3.3v | 1 | generic part, https://www.adafruit.com/product/398[available on Adafruit]
|
||||
| 16x2 LCD backpack | 1 | https://www.adafruit.com/product/781[from Adafruit]
|
||||
| M/M Jumper wires | 3 | generic part
|
||||
|===
|
||||
|
||||
|
||||
173
uart/lcd_uart/lcd_uart.c
Normal file
173
uart/lcd_uart/lcd_uart.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* Example code to drive a 16x2 LCD panel via an Adafruit TTL LCD "backpack"
|
||||
|
||||
Optionally, the backpack can be connected the VBUS (pin 40) at 5V if
|
||||
the Pico in question is powered by USB for greater brightness.
|
||||
|
||||
If this is done, then no other connections should be made to the backpack apart
|
||||
from those listed below as the backpack's logic levels will change.
|
||||
|
||||
Connections on Raspberry Pi Pico board, other boards may vary.
|
||||
|
||||
GPIO 8 (pin 11)-> RX on backpack
|
||||
3.3v (pin 36) -> 3.3v on backpack
|
||||
GND (pin 38) -> GND on backpack
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/binary_info.h"
|
||||
#include "hardware/uart.h"
|
||||
|
||||
// leave uart0 free for stdio
|
||||
#define UART_ID uart1
|
||||
#define BAUD_RATE 9600
|
||||
#define UART_TX_PIN 8
|
||||
#define LCD_WIDTH 16
|
||||
#define LCD_HEIGHT 2
|
||||
|
||||
// basic commands
|
||||
#define LCD_DISPLAY_ON 0x42
|
||||
#define LCD_DISPLAY_OFF 0x46
|
||||
#define LCD_SET_BRIGHTNESS 0x99
|
||||
#define LCD_SET_CONTRAST 0x50
|
||||
#define LCD_AUTOSCROLL_ON 0x51
|
||||
#define LCD_AUTOSCROLL_OFF 0x52
|
||||
#define LCD_CLEAR_SCREEN 0x58
|
||||
#define LCD_SET_SPLASH 0x40
|
||||
|
||||
// cursor commands
|
||||
#define LCD_SET_CURSOR_POS 0x47
|
||||
#define LCD_CURSOR_HOME 0x48
|
||||
#define LCD_CURSOR_BACK 0x4C
|
||||
#define LCD_CURSOR_FORWARD 0x4D
|
||||
#define LCD_UNDERLINE_CURSOR_ON 0x4A
|
||||
#define LCD_UNDERLINE_CURSOR_OFF 0x4B
|
||||
#define LCD_BLOCK_CURSOR_ON 0x53
|
||||
#define LCD_BLOCK_CURSOR_OFF 0x54
|
||||
|
||||
// rgb commands
|
||||
#define LCD_SET_BACKLIGHT_COLOR 0xD0
|
||||
#define LCD_SET_DISPLAY_SIZE 0xD1
|
||||
|
||||
// change to 0 if display is not RGB capable
|
||||
#define LCD_IS_RGB 1
|
||||
|
||||
void lcd_write(uint8_t cmd, uint8_t* buf, uint8_t buflen) {
|
||||
// all commands are prefixed with 0xFE
|
||||
const uint8_t pre = 0xFE;
|
||||
uart_write_blocking(UART_ID, &pre, 1);
|
||||
uart_write_blocking(UART_ID, &cmd, 1);
|
||||
uart_write_blocking(UART_ID, buf, buflen);
|
||||
sleep_ms(10); // give the display some time
|
||||
}
|
||||
|
||||
void lcd_set_size(uint8_t w, uint8_t h) {
|
||||
// sets the dimensions of the display
|
||||
uint8_t buf[] = { w, h };
|
||||
lcd_write(LCD_SET_DISPLAY_SIZE, buf, 2);
|
||||
}
|
||||
|
||||
void lcd_set_contrast(uint8_t contrast) {
|
||||
// sets the display contrast
|
||||
lcd_write(LCD_SET_CONTRAST, &contrast, 1);
|
||||
}
|
||||
|
||||
void lcd_set_brightness(uint8_t brightness) {
|
||||
// sets the backlight brightness
|
||||
lcd_write(LCD_SET_BRIGHTNESS, &brightness, 1);
|
||||
}
|
||||
|
||||
void lcd_set_cursor(bool is_on) {
|
||||
// set is_on to true if we want the blinking block and underline cursor to show
|
||||
if (is_on) {
|
||||
lcd_write(LCD_BLOCK_CURSOR_ON, NULL, 0);
|
||||
lcd_write(LCD_UNDERLINE_CURSOR_ON, NULL, 0);
|
||||
} else {
|
||||
lcd_write(LCD_BLOCK_CURSOR_OFF, NULL, 0);
|
||||
lcd_write(LCD_UNDERLINE_CURSOR_OFF, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_set_backlight(bool is_on) {
|
||||
// turn the backlight on (true) or off (false)
|
||||
if (is_on) {
|
||||
lcd_write(LCD_DISPLAY_ON, (uint8_t *) 0, 1);
|
||||
} else {
|
||||
lcd_write(LCD_DISPLAY_OFF, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_clear() {
|
||||
// clear the contents of the display
|
||||
lcd_write(LCD_CLEAR_SCREEN, NULL, 0);
|
||||
}
|
||||
|
||||
void lcd_cursor_reset() {
|
||||
// reset the cursor to (1, 1)
|
||||
lcd_write(LCD_CURSOR_HOME, NULL, 0);
|
||||
}
|
||||
|
||||
#if LCD_IS_RGB
|
||||
void lcd_set_backlight_color(uint8_t r, uint8_t g, uint8_t b) {
|
||||
// only supported on RGB displays!
|
||||
uint8_t buf[] = { r, g, b };
|
||||
lcd_write(LCD_SET_BACKLIGHT_COLOR, buf, 3);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcd_init() {
|
||||
lcd_set_backlight(true);
|
||||
lcd_set_size(LCD_WIDTH, LCD_HEIGHT);
|
||||
lcd_set_contrast(155);
|
||||
lcd_set_brightness(255);
|
||||
lcd_set_cursor(false);
|
||||
}
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
uart_init(UART_ID, BAUD_RATE);
|
||||
uart_set_translate_crlf(UART_ID, false);
|
||||
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
|
||||
|
||||
bi_decl(bi_1pin_with_func(UART_TX_PIN, GPIO_FUNC_UART));
|
||||
|
||||
lcd_init();
|
||||
|
||||
// define startup sequence and save to EEPROM
|
||||
// no more or less than 32 chars, if not enough, fill remaining ones with spaces
|
||||
uint8_t splash_buf[] = "Hello LCD, from Pi Towers! ";
|
||||
lcd_write(LCD_SET_SPLASH, splash_buf, LCD_WIDTH * LCD_HEIGHT);
|
||||
|
||||
lcd_cursor_reset();
|
||||
lcd_clear();
|
||||
|
||||
#if LCD_IS_RGB
|
||||
uint8_t i = 0; // it's ok if this overflows and wraps, we're using sin
|
||||
const float frequency = 0.1f;
|
||||
float red, green, blue;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
// send any chars from stdio straight to the backpack
|
||||
char c = getchar();
|
||||
// any bytes not followed by 0xFE (the special command) are interpreted
|
||||
// as text to be displayed on the backpack, so we just send the char
|
||||
// down the UART byte pipe!
|
||||
if (c < 128) uart_putc_raw(UART_ID, c); // skip extra non-ASCII chars
|
||||
#if LCD_IS_RGB
|
||||
// change the display color on keypress, rainbow style!
|
||||
red = sin(frequency * i + 0) * 127 + 128;
|
||||
green = sin(frequency * i + 2) * 127 + 128;
|
||||
blue = sin(frequency * i + 4) * 127 + 128;
|
||||
lcd_set_backlight_color(red, green, blue);
|
||||
i++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
BIN
uart/lcd_uart/lcd_uart.fzz
Normal file
BIN
uart/lcd_uart/lcd_uart.fzz
Normal file
Binary file not shown.
BIN
uart/lcd_uart/lcd_uart_bb.png
Normal file
BIN
uart/lcd_uart/lcd_uart_bb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 320 KiB |
@@ -2,7 +2,7 @@ add_executable(uart_advanced
|
||||
uart_advanced.c
|
||||
)
|
||||
|
||||
# Pull in our pico_stdlib which pulls in commonly used features
|
||||
# pull in common dependencies and additional uart hardware support
|
||||
target_link_libraries(uart_advanced pico_stdlib hardware_uart)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
|
||||
Reference in New Issue
Block a user