clean up rocketry code and update readme with dev instructions

This commit is contained in:
Travis Shears 2025-04-06 13:14:24 +02:00
parent 48749aa689
commit 0f1d868f0f
2 changed files with 96 additions and 236 deletions

View file

@ -11,9 +11,9 @@ I have since switch to using C.
Right now the station is fairly limited measuring only temperature, humidity,
and atmospheric pressure. I have plans to expand the project to in the end measure:
- tempature
- humidity
- atmospheric pressure
- tempature
- humidity
- atmospheric pressure
- noise levels
- wind speed
- wind direction
@ -23,12 +23,100 @@ and atmospheric pressure. I have plans to expand the project to in the end measu
## Hardware
Sensors:
- [BME280](https://shop.pimoroni.com/products/bme280-breakout?variant=29420960677971)
- Node1: [BME280](https://shop.pimoroni.com/products/bme280-breakout?variant=29420960677971)
MCs:
- [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/)
- Node1: [Raspberry Pi Pico W](https://www.raspberrypi.com/products/raspberry-pi-pico/)
Other:
- [Weatherproof Enclosure](https://shop.pimoroni.com/products/weatherproof-cover-for-outdoor-sensors?variant=40047884468307)
_Note: I would not recommend buying from pimoroni from EU as shipping tax is huge!_
## Dev
### Env Setup
From build folder run:
```shell
$ cmake -DPICO_BOARD=pico_w ..
```
This creates the needed makefiles
### Build
This turns the test.c file in the root dir into .elf and .uf2 files:
```shell
$ make node1
```
### Flash
Once you have the .uf2 file you can transfer it to the pico by putting the pico
in bootsel mode (hold button and plug it into pc) or you can flash the .elf file
to the pico using `openocd`:
```shell
openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "program node1.elf verify reset exit"
```
*note: after flashing with openocd the program will be paused. To unpause connect and run "continue"*
### Shell
You screen
```shell
$ fd tty.usb /dev
/dev/tty.usbmodem102
$ screen /dev/tty.usbmodem102 115200
```
Exit shell Ctrl+A Ctrl+|
### Open debug connection
```shell
$ openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"
```
then in another window
```shell
$ lldb ./test.elf
```
Once in lldb you can do a bunch of stuff, see https://web.navan.dev/posts/2024-08-08-openocd-macos-lldb.html.
```shell
(lldb) platform select remote-gdb-server
...
(lldb) process connect connect://localhost:3333
```
Set breakpoint:
```shell
(lldb) breakpoint set --hardware --name main
(lldb) continue # Continue execution
(lldb) step # Step in
(lldb) next # Step over
(lldb) finish # Step out
```
Check vars:
```shell
(lldb) frame variable
(lldb) print variable_name
```
Restarting the program:
```shell
(lldb) process plugin packet monitor reset run
```

234
node1.c
View file

@ -1,240 +1,12 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include "blink_led.pio.h"
// #include "hardware/clocks.h"
// == TM1637Display ==
// #define TM1637_CMD_DATA_AUTO 0x40
#define TM1637_DELAY_US 20 // Delay time in microseconds
#define TM1637_CMD_DATA_FIXED 0x44
#define TM1637_CMD_ADDR_START 0xC0
#define TM1637_CMD_DISPLAY 0x88
#define TM1637_BRIGHTNESS 5 // min 0 max 7
typedef struct {
uint clock_pin;
uint data_pin;
} TM1637Display;
TM1637Display tm1637_init(uint clock_pin, uint data_pin);
void tm1637_write_command(const TM1637Display *d, uint8_t command);
void tm1637_display_number(const TM1637Display *d, uint num);
void tm1637_start(const TM1637Display *display);
void tm1637_stop(const TM1637Display *display);
void tm1637_write_bit(const TM1637Display *display, bool bit);
bool tm1637_write_byte(const TM1637Display *display, uint8_t byte);
void tm1637_write_command(const TM1637Display *display, uint8_t command);
const uint8_t tm1637_num_patterns[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
TM1637Display tm1637_init(uint clock_pin, uint data_pin) {
TM1637Display display;
display.clock_pin = clock_pin;
display.data_pin = data_pin;
gpio_init(display.clock_pin);
gpio_init(display.data_pin);
gpio_set_dir(display.clock_pin, GPIO_OUT);
gpio_set_dir(display.data_pin, GPIO_OUT);
tm1637_write_command(&display, TM1637_CMD_DISPLAY | TM1637_BRIGHTNESS);
return display;
}
void tm1637_start(const TM1637Display *display) {
gpio_set_dir(display->data_pin, GPIO_OUT);
gpio_put(display->data_pin, 1);
gpio_put(display->clock_pin, 1);
sleep_us(TM1637_DELAY_US);
gpio_put(display->data_pin, 0);
sleep_us(TM1637_DELAY_US);
gpio_put(display->clock_pin, 0);
}
void tm1637_stop(const TM1637Display *display) {
gpio_set_dir(display->data_pin, GPIO_OUT);
gpio_put(display->clock_pin, 0);
gpio_put(display->data_pin, 0);
sleep_us(TM1637_DELAY_US);
gpio_put(display->clock_pin, 1);
sleep_us(TM1637_DELAY_US);
gpio_put(display->data_pin, 1);
sleep_us(TM1637_DELAY_US);
}
void tm1637_write_bit(const TM1637Display *display, bool bit) {
gpio_put(display->clock_pin, 0);
if (bit)
{
gpio_set_dir(display->data_pin, GPIO_IN);
}
else
{
gpio_set_dir(display->data_pin, GPIO_OUT);
gpio_put(display->data_pin, 0);
}
sleep_us(TM1637_DELAY_US);
gpio_put(display->clock_pin, 1);
sleep_us(TM1637_DELAY_US);
gpio_put(display->clock_pin, 0);
gpio_set_dir(display->data_pin, GPIO_OUT);
}
bool tm1637_write_byte(const TM1637Display *display, uint8_t byte) {
for (int i = 0; i < 8; i++)
{
tm1637_write_bit(display, byte & 0x01);
byte >>= 1;
}
// Wait for ACK
gpio_set_dir(display->data_pin, GPIO_IN);
sleep_us(TM1637_DELAY_US);
gpio_put(display->clock_pin, 0);
sleep_us(TM1637_DELAY_US);
gpio_put(display->clock_pin, 1);
sleep_us(TM1637_DELAY_US);
bool ack = !gpio_get(display->data_pin);
gpio_put(display->clock_pin, 0);
gpio_set_dir(display->data_pin, GPIO_OUT);
return ack;
}
void tm1637_write_command(const TM1637Display *display, uint8_t command) {
tm1637_start(display);
tm1637_write_byte(display, command);
tm1637_stop(display);
}
void tm1637_display_number(const TM1637Display *display, uint num) {
if (num > 9999) return;
uint8_t digits[4] = {0};
// Extract digits and store them in the array from most significant digit to least significant digit
for (int i = 0; i < 4; i++)
{
digits[3 - i] = num % 10;
num /= 10;
}
tm1637_start(display);
bool ack = tm1637_write_byte(display, TM1637_CMD_DATA_FIXED);
tm1637_stop(display);
if(!ack) return tm1637_display_number(display, num);
for (int i = 0; i < 4; i++)
{
tm1637_start(display);
bool ack1 = tm1637_write_byte(display, TM1637_CMD_ADDR_START + i);
bool ack2 = tm1637_write_byte(display, tm1637_num_patterns[digits[i]]);
tm1637_stop(display);
if(!ack1 || !ack2) return tm1637_display_number(display, num);
}
}
// == LEDS ==
void init_leds() {
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
}
void set_led(bool state) {
gpio_put(PICO_DEFAULT_LED_PIN, state);
}
// == RGB_LED ==
// #define RGB_LED_PIN PICO_DEFAULT_LED_PIN
#define RGB_PIO_FREQ 2000
// PIO blink example: https://www.digikey.com/en/maker/projects/raspberry-pi-pico-and-rp2040-cc-part-3-how-to-use-pio/123ff7700bc547c79a504858c1bd8110
// static const uint led_pin = 25;
// static const float pio_freq = 2000;
void init_rgb_leds() {
//Choose PIO instance (0 or 1)
PIO pio = pio0;
// Get first free state machine in PIO 0
uint sm = pio_claim_unused_sm(pio, true);
// Add PIO program to PIO instruction memory. SDK will find location and
// return with the memory offset of the program.
uint offset = pio_add_program(pio, &blink_program);
// Calculate the PIO clock divider
float div = (float)clock_get_hz(clk_sys) / RGB_PIO_FREQ;
// Initialize the program using the helper function in our .pio file
blink_program_init(pio, sm, offset, PICO_DEFAULT_LED_PIN, div);
// Start running our PIO program in the state machine
pio_sm_set_enabled(pio, sm, true);
}
// == Buttons ==
#define ARM_BTN_GPIO 15
void init_btn(uint pin) {
gpio_init(pin);
gpio_set_dir(pin, GPIO_IN);
gpio_pull_up(pin);
}
alarm_id_t armed_timer_id;
int64_t armed_cb() {
printf("ROCKET ARMED\n");
return 0;
}
bool arm_btn_pressed = false;
void check_btns() {
if(!gpio_get(ARM_BTN_GPIO) && !arm_btn_pressed) {
printf("BTN PRESSED\n");
armed_timer_id = add_alarm_in_ms(5000, armed_cb, NULL, false);
arm_btn_pressed = true;
set_led(true);
}
if(gpio_get(ARM_BTN_GPIO) && arm_btn_pressed) {
printf("BTN LET GO\n");
cancel_alarm(armed_timer_id);
arm_btn_pressed = false;
set_led(false);
}
}
int main() {
stdio_init_all();
// const TM1637Display digit_display_001 = tm1637_init(12, 13);
// const TM1637Display digit_display_002 = tm1637_init(14, 15);
// init_btn(ARM_BTN_GPIO);
// init_leds();
init_rgb_leds();
// static absolute_time_t delayed_by_ms (const absolute_time_t t, uint32_t ms)
// volatile bool timer_fired = false;
while (true) {
check_btns();
sleep_us(50);
// for (int i = 0; i <= 9999; i ++) {
// printf("Display: %d \n", i);
// // tm1637_display_number(&digit_display_001, i);
// tm1637_display_number(&digit_display_002, i);
// sleep_ms(100);
// }
sleep_ms(1000);
printf("One Second\n");
}
}