point-2-point demo

Dependencies:   sx12xx_hal

radio chip selection

Radio chip driver is not included, because these options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

TX trigger selection

Edit main.h to define DIGITAL_TRIGGER or ANALOG_TRIGGER to chose whether transmit is initiated by digital pin (button/jumper) or analog pin(s) level change.

This project is intended to be used on two LoRa shields.

Each board sits in continuous RX mode, waiting for request packet.
If the received packet has good CRC, the packet is acknowledged along with read of ADC sample from the replying device.
The original request packet also contains instruction to set level of output pin.

Both sides of the link are running the same code, and each can initiate a transmission at any time.
No addressing is used, so only two nodes can operate on the radio channel.

uart_cmds.cpp

Committer:
Wayne Roberts
Date:
2018-08-01
Revision:
5:e35b1b281466
Parent:
1:d95d135a4fb4

File content as of revision 5:e35b1b281466:

#include <mbed.h>
#include "main.h"

PwmOut pwmA(PB_11); /* CN10-18 */
PwmOut pwmB(PA_15); /* CN7-17 */
PwmOut pwmC(PB_1); /* CN10-24 */
PwmOut pwmD(PC_6); /* CN10-4 */

RawSerial pc(USBTX, USBRX);
char pcbuf[128];
int pcbuf_len;

bool initialized = false;

/* return true for parsed  */
bool parse_radio_rx(uint8_t* rx_buf)
{
    PwmOut* pwmPtr;

    switch (rx_buf[0]) {
        case CMD_PWM_A: pwmPtr = &pwmA; break;
        case CMD_PWM_B: pwmPtr = &pwmB; break;
        case CMD_PWM_C: pwmPtr = &pwmC; break;
        case CMD_PWM_D: pwmPtr = &pwmD; break;
        default: return false;
    }

    pwmPtr->period(1.0 / rx_buf[1]);    // rx_buf[1] is Hz
    pwmPtr->write(rx_buf[2] / 255.0);
    printf("%uHz, duty:%.2f\r\n", rx_buf[1], rx_buf[2]/255.0);
    return true;
}

void cmd_pwm(uint8_t idx)
{
    uint8_t buf[4];
    unsigned ch, p, d;
 
    if (sscanf(pcbuf+idx, "%u %u %u", &ch, &p, &d) != 3) {
        printf("parse fail\r\n");
        return;
    }

    switch (ch) {
        case 0: buf[0] = CMD_PWM_A; break;
        case 1: buf[0] = CMD_PWM_B; break;
        case 2: buf[0] = CMD_PWM_C; break;
        case 3: buf[0] = CMD_PWM_D; break;
    }
    buf[1] = p;
    buf[2] = d;
    radio_tx(buf, 3);
}

void cmd_help(uint8_t args_at);

typedef struct {
    const char* const cmd;
    void (*handler)(uint8_t args_at);
    const char* const arg_descr;
    const char* const description;
} menu_item_t;

const menu_item_t menu_items[] = 
{   /* after first character, command names must be [A-Za-z] */
    { "?", cmd_help, "","show available commands"},
    { "p", cmd_pwm, "%u %u", "set pwm period, duty"},
    { NULL, NULL, NULL, NULL }
};

void cmd_help(uint8_t args_at)
{
    int i;
    for (i = 0; menu_items[i].cmd != NULL ; i++) {
        printf("%s%s\t%s\r\n", menu_items[i].cmd, menu_items[i].arg_descr, menu_items[i].description);
    }
}

void rx_callback()
{
    static uint8_t pcbuf_idx = 0;
    static uint8_t prev_len = 0;;
    char c = pc.getc();
 
    if (c == 8) {
        if (pcbuf_idx > 0) {
            pc.putc(8);
            pc.putc(' ');
            pc.putc(8);
            pcbuf_idx--;
        }
    } else if (c == 3) {    // ctrl-C
        pcbuf_len = -1;
    } else if (c == '\r') {
        if (pcbuf_idx == 0) {
            pcbuf_len = prev_len;
        } else {
            pcbuf[pcbuf_idx] = 0;   // null terminate
            prev_len = pcbuf_idx;
            pcbuf_idx = 0;
            pcbuf_len = prev_len;
        }
    } else if (pcbuf_idx < sizeof(pcbuf)) {
        pcbuf[pcbuf_idx++] = c;
        pc.putc(c);
    }
}

void uart_service()
{
    int i;
    uint8_t user_cmd_len;

    if (!initialized) {
        pc.attach(&rx_callback);
        initialized = true;
    }

    if (pcbuf_len < 0) {    // ctrl-C
        return;
    }
    if (pcbuf_len == 0)
        return;
        
    printf("\r\n");
        
    /* get end of user-entered command */
    user_cmd_len = 1;   // first character can be any character
    for (i = 1; i <= pcbuf_len; i++) {
        if (pcbuf[i] < 'A' || (pcbuf[i] > 'Z' && pcbuf[i] < 'a') || pcbuf[i] > 'z') {
            user_cmd_len = i;
            break;
        }
    }
 
    for (i = 0; menu_items[i].cmd != NULL ; i++) {
        int mi_len = strlen(menu_items[i].cmd);
 
        if (menu_items[i].handler && user_cmd_len == mi_len && (strncmp(pcbuf, menu_items[i].cmd, mi_len) == 0)) {
            while (pcbuf[mi_len] == ' ')   // skip past spaces
                mi_len++;
            menu_items[i].handler(mi_len);
            break;
        }
    }
 
    pcbuf_len = 0;
    printf("> ");
    fflush(stdout); 
}