Final firmware for ConnectorBox TPH 1.0 (NXP LPC1768).

Dependencies:   USBDevice mbed

TSCZ ConnectorBox (Czech only)

/media/uploads/Neolker/total.png

Funkce

  • 40x kanálů propojených s měřicími kartami Fluke 2638A
    • 18x 4-vodičové RTD
    • 2x 4-vodičové snímače tlaku s externím napájením
    • 20x rozpoznání 1-wire ID čipů (DS2401+, DS24B33+, ...)
  • 2x UART rozhraní pro komunikaci s Rotronic HC2-S snímači (teplota, rel. vlhkost)
  • USB Serial komunikace s PC (921600 Baud)
  • USB_LED - signalizační ovladatelná LED
  • LEMO konektory

Seznam příkazů

PříkazPopis funkcePočet příchozích BajtůDoba odezvy (maximální)
aPřečte všechny ID a ROT568 B1154 ms
dLadění ROT_01 (RAW Data)183 nebo 284 B433 ms
hZobrazí tento HELP507 B507 ms
iPřečte všechna ID500 B591 ms
pPeriodické čtení všech ROT102 B až variabilní599 ms až variabilní
rPřečte všechny ROT68 B566 ms
sSignalizace pomocí USB_LED14 B14 ms
tTest ID_01 a ROT_0159 B313 ms
vZobrazí verzi firmware252 B252 ms

Pozn.: Nezáleží na velikosti písmene, tedy "a" provede to samé jako "A"

Naprogramování MCU

Potřebný SW a HW

  • Naimportovaný tento projekt
  • Pro převod souboru z .BIN na .HEX program Hexplorer
  • Pro naprogramování MCU program Flash Magic
  • Univerzální převodník USB <-> Serial UART - PRG 1.0 /media/uploads/Neolker/prg_top.png /media/uploads/Neolker/prg_bot.png
  • Propojovací kablíky
  • USB kabel pro napájení ConnectorBox

Postup programování

  1. V mbed compilátoru zkompilujte projekt pro platformu mbed LPC1768
  2. Stáhnutou binárku TSCZ_ConnectorBox_LPC1768_2-0.bin otevřete v Hexploreru
  3. V Hexploreru potom vyexportujte HEX soubor ve formátu Intel Hex: /media/uploads/Neolker/flash_1.png
  4. Připojte USB kabel ke ConnectorBoxu kvůli napájení
  5. Propojte Univerzální převodník PRG 1.0 a programovací piny ConnectorBoxu (TX<->RX, RX<->TX a GND<->GND) /media/uploads/Neolker/prog.png
  6. Připojte PRG 1.0 k PC a zjistěte si přes Správce zařízení příslušné číslo COM portu (v tomto případě COM 8)
  7. Na ConnectorBox DPS stiskněte nejprve ISP tlačítko, následně stiskněte RESET tlačítko a uvolněte je v obraceném pořadí, tzn. nejprve uvolnit RESET a poté ISP -> MCU tímto přejde do "flashovacího" módu
  8. HEX soubor TSCZ_ConnectorBox_LPC1768_2-0.hex nahrajte pomocí Flash Magic s tímto nastavením /media/uploads/Neolker/flash_2.png
  9. Průběh programování můžete sledovat dole ve statusové liště Flash Magic
  10. Zhruba po 5 minutách by mělo být hotovo se zeleným výpisem Finished ve statusové liště viz předchozí bod
  11. Nyní odpojte Univerzální převodník PRG 1.0
  12. A resetujte ConnectorBox stisknutím tlačítka RESET, nebo odpojte a připojte USB kabel ConnectorBoxu
  13. Gratuluji, v MCU nyní běží nový firmware

Instalace

  1. Stáhnout USB-Serial driver: TSCZ_ConnectorBox_Driver.inf
  2. Připojit ConnectorBox USB kabelem k PC. Po připojení by se mělo zobrazit toto: /media/uploads/Neolker/install_1.png
  3. Ve Správci zařízení pravým tlačítkem na CDC DEVICE vybrat Aktualizovat software ovladače... /media/uploads/Neolker/install_2.png
  4. Dále zvolte Vyhledat ovladač v počítači a najděte umístění driveru z kroku č. 1.
  5. Driver je nepodepsaný, tedy jen potvrďte bezpečnostní hlášku pro pokračovaní instalace volbou Přesto nainstalovat...
  6. Po úspěšné instalaci bude ve Správci zařízení nové zařízení pod sekcí Porty s názvem TSCZ ConnectorBox /media/uploads/Neolker/install_3.png
  7. Číslo portu (v tomto případě COM20) si poznamenejte pro další použití

Použití

Terminál

  • Funkčnost můžete ověřit v oblíbeném terminálu PuTTY s tímto nastavením: /media/uploads/Neolker/use_1.png
  • Příklad výpisu v terminálu po vyzkoušení příkazů (w - neznámý příkaz, h - help, v - verze): /media/uploads/Neolker/use_2.png
  • Každý řádek výpisu je ukončený novým řádkem dle standardu MS Windows: CR+LF, "\r\n", 0x0D0A

LabVIEW

  • Díky jednoduché komunikaci po virtuální seriové lince, pomocí příkazů a odpovědí, není problém komunikovat s ConnectorBoxem pomocí VISA driveru v jakékoliv verzi LabVIEW od National Instruments.
  • Pozor u funkcí VISA Read a VISA Write, Windows ovladač Usbser.sys obsahuje chybu, že při asynchronním módu komunikace nastává náhodně po nějaké době BSOD aneb "modrá smrt", která vám dokáže velmi znepříjemnit den, protože po následujícím nutném tvrdém restartu přijdete o veškerou rozdělanou práci. Řešení jsou k dispozici dvě:
    1. Hotfix záplata přímo od Microsoftu je ke stažení zde KB2964073 (pouze pro Windows 7).
    2. Daleko lepší je přepnout obě funkce VISA Read a VISA Write v LabVIEW vždy na Synchronní mód: /media/uploads/Neolker/labview_bsod.png

main.cpp

Committer:
Neolker
Date:
2016-09-26
Revision:
1:40a75dc71d03
Parent:
0:43fd4f873193
Child:
2:35291967fdfb

File content as of revision 1:40a75dc71d03:

/*
* -------------------------------
* ConnectorBoxFW 3.0 (2016-09-25)
* -------------------------------
* Firmware for ConnectorBox TPH 1.0 (NXP LPC1768).
*
* Copyright (c) 2016, Martin Wolker (neolker@gmail.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     - Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     - Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     - Neither the name of Martin Wolker nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL MARTIN WOLKER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "mbed.h"
#include "USBSerial.h"

#define ROT_SPEED           19200
#define ROT_TIMEOUT         250
#define ROT_INTERVAL        350
#define TEMPERATURE_START   29
#define TEMPERATURE_END     35
#define HUMIDITY_START      12
#define HUMIDITY_END        18
#define SERIAL_START        77
#define SERIAL_END          85
#define LED_DELAY           100

USBSerial       PC;
Serial          ROT_01(p28, p27);
Serial          ROT_02(p9, p10);
DigitalInOut    ID_01(p11);
DigitalInOut    ID_02(p12);
DigitalInOut    ID_03(p13);
DigitalInOut    ID_04(p14);
DigitalInOut    ID_05(p21);
DigitalInOut    ID_06(p22);
DigitalInOut    ID_07(p25);
DigitalInOut    ID_08(p26);
DigitalInOut    ID_09(p5);
DigitalInOut    ID_10(p6);
DigitalInOut    ID_11(p7);
DigitalInOut    ID_12(p8);
DigitalInOut    ID_13(p29);
DigitalInOut    ID_14(p30);
DigitalInOut    ID_15(p18);
DigitalInOut    ID_16(p17);
DigitalInOut    ID_17(p16);
DigitalInOut    ID_18(p15);
DigitalInOut    ID_19(p20);
DigitalInOut    ID_20(p19);
DigitalOut      LED(LED1);

enum DELAY {A = 6, B = 64, C = 60, D = 10, E = 9, F = 55, G = 0, H = 480, I = 70, J = 410};

void GetHelp()
{
    PC.printf("-------------------------------------\r\n");
    PC.printf("|      HELP - List of commands      |\r\n");
    PC.printf("-------------------------------------\r\n");
    PC.printf("| a -> Read all ID and all ROT      |\r\n");
    PC.printf("| d -> Debug of ROT_01 (RAW DATA)   |\r\n");
    PC.printf("| h -> Get this HELP                |\r\n");
    PC.printf("| i -> Read all ID                  |\r\n");
    PC.printf("| p -> Periodic reading of all ROT  |\r\n");
    PC.printf("| r -> Read all ROT                 |\r\n");
    PC.printf("| s -> Signalization by USB LED     |\r\n");
    PC.printf("| t -> Test of ID_01 and ROT_01     |\r\n");
    PC.printf("| v -> Get version of firmware      |\r\n");
    PC.printf("-------------------------------------\r\n");
}

void Blink(int info)
{
    if (info) PC.printf("LED blinking\r\n");
    for (int i = 0; i < 2; i++) {
        LED = 1;
        wait_ms(LED_DELAY);
        LED = 0;
        wait_ms(LED_DELAY);
    }
}

int Reset(DigitalInOut& pin)
{
    pin.output();
    pin = 0;
    wait_us(H);
    pin.input();
    wait_us(I);
    uint32_t result = pin;
    wait_us(J);
    return result;
}

void WriteBit(DigitalInOut& pin, uint32_t bit)
{
    pin.output();
    if (bit) {
        pin = 0;
        wait_us(A);
        pin.input();
        wait_us(B);
    } else {
        pin = 0;
        wait_us(C);
        pin.input();
        wait_us(D);
    }
}

uint32_t ReadBit(DigitalInOut& pin)
{
    uint32_t bit_value;
    pin.output();
    pin = 0;
    wait_us(A);
    pin.input();
    wait_us(E);
    bit_value  = pin;
    wait_us(F);
    return bit_value;
}

void WriteByte(DigitalInOut& pin, uint32_t byte)
{
    for (uint32_t bit = 0; bit < 8; ++bit) {
        WriteBit(pin, byte & 0x01);
        byte >>= 1;
    }
}

uint32_t ReadByte(DigitalInOut& pin)
{
    uint32_t byte = 0;
    for (uint32_t bit = 0; bit < 8; ++bit) {
        byte |= (ReadBit(pin) << bit);
    }
    return byte;
}

void GetID(DigitalInOut& pin, int number)
{
    Reset(pin);
    WriteByte(pin, 0x33);
    int B8 = ReadByte(pin);
    int B7 = ReadByte(pin);
    int B6 = ReadByte(pin);
    int B5 = ReadByte(pin);
    int B4 = ReadByte(pin);
    int B3 = ReadByte(pin);
    int B2 = ReadByte(pin);
    int B1 = ReadByte(pin);
    PC.printf("ID_%02d: %02X%02X%02X%02X%02X%02X%02X%02X\r\n", number, B1, B2, B3, B4, B5, B6, B7, B8);
}

void GetROT(Serial& port, int number, int debug)
{
    Timer t;
    int position = 0;
    char symbol = '0';
    char buffer[255] = "";
    t.start();
    port.printf("{F99RDD-\r");
    while((symbol != '\r') && (t.read_ms() < ROT_TIMEOUT)) {
        if(port.readable()) {
            symbol = port.getc();
            buffer[position] = symbol;
            position++;
        }
    }
    t.stop();
    if (debug) {
        PC.printf("------DEBUG_START-------\r\n");
        PC.printf("Reading time is: %d ms\r\n", t.read_ms());
        PC.printf("Count of characters: %d\r\n", position);
        PC.printf("ROT_%02d (RAW DATA):\r\n", number);
        if (position == 0) {
            PC.printf("N/A\r\n");
        } else {
            for (int d = 0; d < 105; d++) {
                PC.printf("%c", buffer[d]);
            }
            PC.printf("\n");
        }
        PC.printf("ROT_%02d (PARSED DATA):\r\n", number);
    }
    t.reset();
    if ((position != 105) || (buffer[16] == '-')) {
        PC.printf("ROT_%02d:   0,00;   0,00; 00000000\r\n", number);
    } else {
        PC.printf("ROT_%02d: ", number);
        for (int i = TEMPERATURE_START; i < TEMPERATURE_END; i++) {
            if (buffer[i] == '.') {
                PC.printf(",");
            } else {
                PC.printf("%c", buffer[i]);
            }
        }
        PC.printf("; ");
        for (int j = HUMIDITY_START; j < HUMIDITY_END; j++) {
            if (buffer[j] == '.') {
                PC.printf(",");
            } else {
                PC.printf("%c", buffer[j]);
            }
        }
        PC.printf("; ");
        for (int k = SERIAL_START; k < SERIAL_END; k++) {
            PC.printf("%c", buffer[k]);
        }
        PC.printf("\r\n");
    }
    if (debug) PC.printf("-------DEBUG_END--------\r\n");
}

void GetVersion()
{
    PC.printf("----------------------------------\r\n");
    PC.printf("|      ConnectorBox TPH 1.0      |\r\n");
    PC.printf("----------------------------------\r\n");
    PC.printf("| FW version: 3.0 (2016-09-25)   |\r\n");
    PC.printf("| Author:     Martin Wolker      |\r\n");
    PC.printf("| Contact:    neolker@gmail.com  |\r\n");
    PC.printf("----------------------------------\r\n");
}

int main(void)
{
    ROT_01.baud(ROT_SPEED);
    ROT_02.baud(ROT_SPEED);
    int flag = 1;
    LED = 0;
    Blink(0);
    wait(1);
    while(1) {
        if (PC.readable()) {
            switch(PC.getc()) {
                case 'A':
                case 'a':
                    GetID(ID_01, 1);
                    GetID(ID_02, 2);
                    GetID(ID_03, 3);
                    GetID(ID_04, 4);
                    GetID(ID_05, 5);
                    GetID(ID_06, 6);
                    GetID(ID_07, 7);
                    GetID(ID_08, 8);
                    GetID(ID_09, 9);
                    GetID(ID_10, 10);
                    GetID(ID_11, 11);
                    GetID(ID_12, 12);
                    GetID(ID_13, 13);
                    GetID(ID_14, 14);
                    GetID(ID_15, 15);
                    GetID(ID_16, 16);
                    GetID(ID_17, 17);
                    GetID(ID_18, 18);
                    GetID(ID_19, 19);
                    GetID(ID_20, 20);
                    GetROT(ROT_01, 1, 0);
                    GetROT(ROT_02, 2, 0);
                    Blink(0);
                    break;
                case 'D':
                case 'd':
                    GetROT(ROT_01, 1, 1);
                    Blink(0);
                    break;
                case 'H':
                case 'h':
                    GetHelp();
                    break;
                case 'I':
                case 'i':
                    GetID(ID_01, 1);
                    GetID(ID_02, 2);
                    GetID(ID_03, 3);
                    GetID(ID_04, 4);
                    GetID(ID_05, 5);
                    GetID(ID_06, 6);
                    GetID(ID_07, 7);
                    GetID(ID_08, 8);
                    GetID(ID_09, 9);
                    GetID(ID_10, 10);
                    GetID(ID_11, 11);
                    GetID(ID_12, 12);
                    GetID(ID_13, 13);
                    GetID(ID_14, 14);
                    GetID(ID_15, 15);
                    GetID(ID_16, 16);
                    GetID(ID_17, 17);
                    GetID(ID_18, 18);
                    GetID(ID_19, 19);
                    GetID(ID_20, 20);
                    Blink(0);
                    break;
                case 'P':
                case 'p':
                    PC.printf("-------------START--------------\r\n");
                    while(flag) {
                        GetROT(ROT_01, 1, 0);
                        GetROT(ROT_02, 2, 0);
                        Blink(0);
                        wait_ms(ROT_INTERVAL);
                        if (PC.readable()) {
                            PC.getc();
                            PC.printf("--------------END---------------\r\n");
                            flag = 0;
                        }
                    }
                    flag = 1;
                    break;
                case 'R':
                case 'r':
                    GetROT(ROT_01, 1, 0);
                    GetROT(ROT_02, 2, 0);
                    Blink(0);
                    break;
                case 'S':
                case 's':
                    Blink(1);
                    break;
                case 'T':
                case 't':
                    GetID(ID_01, 1);
                    GetROT(ROT_01, 1, 0);
                    Blink(0);
                    break;
                case 'V':
                case 'v':
                    GetVersion();
                    Blink(0);
                    break;
                default:
                    PC.printf("Unknown command, try \"h\" for HELP!\r\n");
                    Blink(0);
                    break;
            }
        }
    }
}