h10 technical documentation Buy

LoRa HAT for Fox Board D27

BRIZIO-H10 is an HAT designed to tranform your FOX Board D27 SBC in a personal LoRa gateway matched to work with modules Berta H10.

Main features

The Brizio-H10 is equipped with :

  • H10 Module
  • 2 2x40 male connectors
  • Antenna connector
  • Debug Port Header
  • Reset push button
  • Green Led

How does it work ?

The Brizio-H10 board houses a H-10 Module that can receive, via LoRa, data sent by on-field H10 sensors, filters it using the on-board firmware and transmits JSON strings to the FOX Board D27 via one of its serial ports.

Wirings between Brizio-H10 HAT and the Fox Board D27

The following table shows which pins of the FOX Board D27 SBC are used to exchange data and program the Brizio-H10

Signals Fox D27 pins H10 lines Data Prog
RXD2 (PD19) J2.9 TXD X
TXD2 (PD20) J2.10 RXD X
WAKE (PB9) J2.15 X
SWCLK (PA30) J2.25 X
NRST (PC21) J2.23 X
SWDIO (PA31) J2.24 X

Implementing a stand alone Lora concentrator.

This block diagram shows a simple application where a system based on FOX Board D27 SBC and Brizio-H10, implements a local LoRa concentrator, showing on a LCD display Infos received from remote nodes.

Following is an excerpt from the python based application used to implement the local gateway.

def report_node_type(strjson, cfg_dict):

    nodeclass = {
        "1"  : "HT",
        "2"  : "AT",
        "3"  : "CO2T",
        "4"  : "D",
        "5"  : "CMT"
    }
    dictH10 = dict()
    lensj = len(strjson)
    if lensj != 0:
        dictH10 = json.loads(strjson)
        if "s_class" in dictH10:
            s_class = dictH10["s_class"]
            if((s_class>=0)and(s_class<=5)):
                ctime = time.time()
                ltime = time.localtime(ctime)
                ms = int((ctime - int(ctime)) * 1000)
                s_time = "@ {0:02d}:{1:02d}:{2:02d}.{3:03d}".format(ltime.tm_hour, ltime.tm_min, ltime.tm_sec,ms)
                s_strclass = "{0:d}".format(s_class)
                strclass = nodeclass[s_strclass]
                print('{0:s} Node {1:s}'.format(strclass, s_time))
                #   Extract and handle infos stored in the packet header that are shared among all kind of nodes 
                #   such as RSSI, SNR, CLASS, VCC, VPANEL
                retblnAlert = report_node_header(dictH10)
                #   Select node type to handle specific node infos
                match(s_class):
                    case 1:
                        #   Processs node Humidity & Temperature
                        report_ht_node(dictH10, cfg_dict)
                    case 2:
                        #   Process node Acceleration & Temperature
                        report_at_node(dictH10)
                    case 3:
                        #   Process node CO2 & Temperature
                        report_co2t_node(dictH10)
                    case 4:
                        #   Process node Distance
                        report_d_node(dictH10)
                    case 5:
                        #   Process node Cicciometocca
                        report_cmt_node(dictH10, cfg_dict)
                    case _:
                        print('UNKOWN Node {0:s}'.format(s_time))
            else:
                print("NOT An Acme Node : Wrong Class {0:3d}".format(sclass))
        else:
            print("NOT An Acme Node : Missing Class")
    else:
        print("NOT An Acme Node : Empy String")

print("\n\nStarting FoxD27 - Local Concentrator\n")


#
#
#   Main
#
#

#
#   Load and check configuration file eventually defining defaults if necessary
#
cfg_dict=loadCfgFile()

#
#   Opening serial port
#
ser = serial.Serial(
    port=cfg_dict["serial_port"],
    baudrate=cfg_dict["serial_baud"],
    timeout=cfg_dict["serial_to"],
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
)

#
#   Run main loop
#
while True:
    #   Check serial port for incoming data
    bytesToRead = ser.inWaiting()
    if bytesToRead>0:
        #   Data is available, read it. 
        value=ser.read(bytesToRead)
        #   Append data to buffer
        bufferjson = bufferjson + value.decode("utf-8")
        #   Look for and extract a json string 
        jsonBH10,bufferjson = xtract_json_from_string(bufferjson)
        if len(jsonBH10)>0:
        #   Json string available, process it
            print("\n\nReceived Packet :")
            print("%s\n" % jsonBH10)
            report_node_type(jsonBH10, cfg_dict)
    else:
        time.sleep(.1)

Implementing a Lora gateway.

This block diagram shows a simple application where a system based on FOX Board D27 SBC and Brizio-H10, implements a LoRa gateway

Brizio-H10 firmware

Both the forementioned applications are based on the same firmware running on the Brizio-H10, based on RIOT

Following is an excerpt from the C based application used to implement the local gateway.

int main(void)
{
    lora_state_t lora;
    int res;
    printf("\n");
    printf("-------------------------------------\n");
    printf("-  Packet Forwarder  For Maker Fair -\n");
    printf("-          by Acmesystems           -\n");
    printf("-  Version  : %s              -\n", FW_VERSION);
    printf("-  Compiled : %s %s  -\n", __DATE__, __TIME__);
    printf("-------------------------------------\n\n");

   //   Init uart rx ringbuffer
    ringbuffer_init(&u_ctx.rx_buf, u_ctx.rx_mem, UART_BUF_SIZE);
    //  Init uart, with error handling
    res = uart_init(UART_PORT, UART_SPEED, rx_cb, NULL);
    if (res == UART_NOBAUD) {
        printf("Error: Given baudrate (%lu) not possible\n", UART_SPEED);
        return 1;
    }
    else if (res != UART_OK) {
        puts("Error: Unable to initialize UART device");
        return 1;
    }
    b_init();

    printf("Success: Initialized UART at BAUD %lu\n", UART_SPEED);    
    printf("Initialization OK.\n");

    memset(&lora, 0, sizeof(lora));
    lora.bandwidth = DEFAULT_LORA_BANDWIDTH;
    lora.spreading_factor = DEFAULT_LORA_SPREADING_FACTOR;
    lora.coderate = DEFAULT_LORA_CODERATE;
    lora.channel = DEFAULT_LORA_CHANNEL;
    lora.power = DEFAULT_LORA_POWER;
    lora.data_cb = *dump_message;
    if (lora_init(&(lora)) != 0) {
        return 1;
    }
    report_lora_setup();
    lora_listen();
    puts("Listen mode set; waiting for messages");
    thread_sleep();
    return 0;
}

Programming the Brizio-H10 Firmware

Brizio-H10 firmware is programmed from the FOX Board D27 SBC as explained in OpenOCD on FOX Board D27

Device tree source

The following statements is included in the FOX Board D27 SBC acme-roadrunner.dts file to enable the serial port used to exchange data back and forth between Brizio-H10 and FOX Board D27 SBC

uart2: serial@f8024000 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart2_ioset3>;
    atmel,use-dma-rx;
    atmel,use-dma-tx;
    status = "okay";
};


pinctrl@fc038000 {
    pinctrl_uart2_ioset3: uart2_ioset3 {
        pinmux = <PIN_PD19__URXD2>,
             <PIN_PD20__UTXD2>;
        bias-disable;
    };
};

Documentation

Fabrizio Rinalduzzi
Hardware designer, firmware and (sometimes) software developer, with a soft spot for compiled code and good music.

"A common mistake that people make when trying to design something completely foolproof
is to underestimate the ingenuity of complete fools."
-Douglas Adams-


Webpage: Fabrizio Rinalduzzi Electronic Systems DESIGN ---
Sergio Tanzilli
Systems designer, webmaster of www.acmesystems.it and founder of Acme Systems srl

Personal email: tanzilli@acmesystems.it
Web pages: https://www.acmesystems.it --- https://www.acmestudio.it
Github repositories: https://github.com/tanzilli --- https://github.com/acmesystems
Telegram group dedicated to the Acme Systems boards: https://t.me/acmesystemssrl

Home page h10 technical documentation Buy