From 51496467178a72505837bba6fbb39a3210fb89e1 Mon Sep 17 00:00:00 2001 From: klaute Date: Mon, 19 Sep 2016 22:38:37 +0200 Subject: [PATCH] Baudrate increased to 115200. Added a python script to manage the SWR meter hard- and firmware behaviour. --- firmware/firmware.ino | 4 +- tools/meas.py | 468 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 471 insertions(+), 1 deletion(-) create mode 100644 tools/meas.py diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 8bc1b56..1633ff8 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -22,7 +22,7 @@ void setup() pinMode(A1, INPUT); // Init the serial connection - Serial.begin(57600); + Serial.begin(115200); // initialize the command control module cc_init(); @@ -73,6 +73,8 @@ void loop() cc_processData(c); } + //cc_abort(); + delay(100); } diff --git a/tools/meas.py b/tools/meas.py new file mode 100644 index 0000000..ff7e224 --- /dev/null +++ b/tools/meas.py @@ -0,0 +1,468 @@ + +############################################################################### + +import argparse +import threading +import time +import serial +import copy +import binascii + +############################################################################### + +parser = argparse.ArgumentParser(description='SWR meter helper tool.') +parser.add_argument("-d", "--device", type=str, help="The control device like /dev/ttyUSB0 or COM3.") +# start_freq +parser.add_argument("-s", "--start_freq", type=int, help="") +# end_freq +parser.add_argument("-e", "--end_freq", type=int, help="") +# intervall +parser.add_argument("-i", "--intervall", type=int, help="") +# step_freq +parser.add_argument("-p", "--step_freq", type=int, help="") +# drive_str +parser.add_argument("-a", "--drive_str", type=int, help="") +# start measurement +parser.add_argument("-m", "--start_meas", default=False, help="", action='store_true') +# output file (CSV) +parser.add_argument("-o", "--output_file", type=str, help="") +# show graphical results +parser.add_argument("-g", "--show_graph", default=False, help="", action='store_true') +# get config +parser.add_argument("-c", "--get_config", default=False, help="", action='store_true') + +############################################################################### + +MSG_SOD1 = 0x3c +MSG_SOD2 = 0x3e +MSG_EOD1 = 0x0d +MSG_EOD2 = 0x0a + +MSG_TYPE_ANSWER_OK = 0x01 +MSG_TYPE_ANSWER_NOK = 0x02 +MSG_TYPE_MEAS_FREQ_INFO = 0x03 +MSG_TYPE_MEAS_END_INFO = 0x04 +MSG_TYPE_CONFIG = 0x05 + +MSG_TYPE_ANSWER_OK_DATA_TO_RECV = 0 +MSG_TYPE_ANSWER_NOK_DATA_TO_RECV = 0 +MSG_TYPE_MEAS_FREQ_INFO_DATA_TO_RECV = 8 +MSG_TYPE_MEAS_END_INFO_DATA_TO_RECV = 0 +MSG_TYPE_CONFIG_DATA_TO_RECV = 15 + +CC_CMD_SET_START_FREQ = 0x01 +CC_CMD_SET_END_FREQ = 0x02 +CC_CMD_SET_INTERVALL = 0x03 +CC_CMD_SET_DRIVE_STRENGTH = 0x04 +CC_CMD_SET_FREQ_STEP = 0x05 +CC_CMD_START_MEASUREMENT = 0x06 +CC_CMD_GET_CONFIG = 0x10 + +############################################################################### + +TIMEOUT_CNT_MAX = 50 +MAIN_LOOP_DELAY_S = 0.05 +THREAD_LOOP_DELAY_S = 0.01 + +############################################################################### + +MUX_MIN_VAL = 0 +MUX_MAX_VAL = 7 + +############################################################################### + +ser = None +device = "/dev/ttyUSB0" + +############################################################################### + +CC_STATE_WAIT_SOD1 = 0x01 +CC_STATE_WAIT_SOD2 = 0x02 +CC_STATE_READ_DATA = 0x03 +CC_STATE_WAIT_EOD1 = 0x04 +CC_STATE_WAIT_EOD2 = 0x05 +CC_STATE_GET_TYPE = 0x06 + +cc_state = CC_STATE_WAIT_SOD1 + +cc_state_list = [ CC_STATE_WAIT_SOD1, + CC_STATE_WAIT_SOD2, + CC_STATE_READ_DATA, + CC_STATE_WAIT_EOD1, + CC_STATE_WAIT_EOD2 ] + +cc_state_fn = {} + +msg_type_list = [ MSG_TYPE_ANSWER_OK, + MSG_TYPE_ANSWER_NOK, + MSG_TYPE_MEAS_FREQ_INFO, + MSG_TYPE_CONFIG, + MSG_TYPE_MEAS_END_INFO, ] + +msg_type_data_to_read = { MSG_TYPE_ANSWER_OK : MSG_TYPE_ANSWER_OK_DATA_TO_RECV, + MSG_TYPE_ANSWER_NOK : MSG_TYPE_ANSWER_NOK_DATA_TO_RECV, + MSG_TYPE_MEAS_FREQ_INFO : MSG_TYPE_MEAS_FREQ_INFO_DATA_TO_RECV, + MSG_TYPE_CONFIG : MSG_TYPE_CONFIG_DATA_TO_RECV, + MSG_TYPE_MEAS_END_INFO : MSG_TYPE_MEAS_END_INFO_DATA_TO_RECV, } + +msg_type = 0 + +cc_data_read = 0 +cc_data_buffer = [] + +# yes a separate counter to manage the order of the received messages +cc_message_cnt = 0 +cc_received_messages = [] + +############################################################################### + +thread_obj = None +thread_lock = None +thread_started = False +thread_stop = False + +############################################################################### + +def cc_init(): + + global cc_state_fn + global cc_state + + cc_state = CC_STATE_WAIT_SOD1 + + cc_state_fn = { CC_STATE_WAIT_SOD1 : cc_state_fn_wait_for_sod1, + CC_STATE_WAIT_SOD2 : cc_state_fn_wait_for_sod2, + CC_STATE_WAIT_EOD1 : cc_state_fn_wait_for_eod1, + CC_STATE_WAIT_EOD2 : cc_state_fn_wait_for_eod2, + CC_STATE_GET_TYPE : cc_state_fn_get_type, + CC_STATE_READ_DATA : cc_state_fn_read_data, } + +########## function to call by the thread +def cc_dataReceiverThread(): + + global ser + global cc_state + global cc_state_fn + global thread_started + global thread_stop + + thread_started = True + + while thread_stop == False: + + # 1. read byte from serial port into incoming + incoming = [] + bytesToRead = ser.inWaiting() + if bytesToRead > 0: + incoming = list(ser.read(64)) + + # 2. process the received data + for c in incoming: + c = int(binascii.hexlify(c), 16) + + # call the cc_state specific function to process the currently received byte + cc_state_fn[cc_state](c) + + if cc_state not in cc_state_list: + cc_state = CC_STATE_WAIT_SOD1 + + time.sleep(THREAD_LOOP_DELAY_S) + + thread_started = False + +########## +def cc_startReceiverThread(): + + global thread_obj + global thread_lock + global thread_stop + + if thread_started == False: + thread_lock = threading.Lock() + thread_obj = threading.Thread(target=cc_dataReceiverThread) + thread_obj.start() + thread_stop = False + +########## +def cc_stopReceiverThread(): + + global thread_obj + global thread_started + global thread_stop + + if thread_started == True: + thread_stop = True + thread_obj.join() # wait for the thread to finish + +##### CC_STATE_WAIT_SOD1 +def cc_state_fn_wait_for_sod1(c): + + global cc_data_read + global msg_type + global cc_data_buffer + global cc_state + + cc_data_read = 0 + msg_type = 0 + cc_data_buffer = [] + + if c == MSG_SOD1: + cc_state = CC_STATE_WAIT_SOD2 + else: + cc_state = CC_STATE_WAIT_SOD1 + +##### CC_STATE_WAIT_SOD2 +def cc_state_fn_wait_for_sod2(c): + + global cc_state + + if c == MSG_SOD2: + cc_state = CC_STATE_GET_TYPE + else: + cc_state = CC_STATE_WAIT_SOD1 + +##### CC_STATE_GET_TYPE +def cc_state_fn_get_type(c): + + global msg_type + global cc_state + + if c in msg_type_list: + msg_type = c + + if msg_type_data_to_read[msg_type] > 0: + cc_state = CC_STATE_READ_DATA + else: + cc_state = CC_STATE_WAIT_EOD1 + else: + cc_state = CC_STATE_WAIT_SOD1 + +##### CC_STATE_READ_DATA +def cc_state_fn_read_data(c): + + global cc_data_buffer + global cc_data_read + global cc_state + + if cc_data_read <= msg_type_data_to_read[msg_type] - 1: + cc_data_buffer.append(c) + cc_data_read = cc_data_read + 1 + + if cc_data_read == msg_type_data_to_read[msg_type]: + cc_state = CC_STATE_WAIT_EOD1 + +##### CC_STATE_WAIT_EOD1 +def cc_state_fn_wait_for_eod1(c): + + global cc_state + + if c == MSG_EOD1: + cc_state = CC_STATE_WAIT_EOD2 + else: + cc_state = CC_STATE_WAIT_SOD1 + +##### CC_STATE_WAIT_EOD2 +def cc_state_fn_wait_for_eod2(c): + + global thread_lock + global cc_message_cnt + global cc_state + + if c == MSG_EOD2: + is_message_read = False + thread_lock.acquire() + cc_received_messages.append([ cc_message_cnt, + msg_type, + is_message_read, + copy.deepcopy(cc_data_buffer) ]) + thread_lock.release() + cc_message_cnt = cc_message_cnt + 1 + + cc_state = CC_STATE_WAIT_SOD1 + +############################################################################### + +##### +def openSerialDevice(d): + + global ser + + # Why 115200? Because the host defines the baudrate for the USB serial connection. + try: + ser = serial.Serial(d, 115200, timeout=0) + except: + print "ERROR: Can't open the serial device " + device + exit(1) + +##### +def closeSerialDevice(): + + global ser + + ser.close() + +##### +def sendSerialData(data): + + global ser + + ser.write(bytearray([ MSG_SOD1, MSG_SOD2 ])) + ser.write(bytearray(data)) + ser.write(bytearray([ MSG_EOD1, MSG_EOD2 ])) + +############################################################################### + +if __name__ == "__main__": + + cc_init() + + # parse the commandline arguments + args = parser.parse_args() + + dataSend = 0 + timeout = 0 + + # 1. open serial device or abort + if args.device != None: + device = args.device + + openSerialDevice(device) + + # 2. start thread to poll cc_dataReceiverThread() + cc_startReceiverThread() + + # 3. get and process the commandline arguments/parameter + if args.get_config == True: + print "Send: GET_CONFIG" + sendSerialData([CC_CMD_GET_CONFIG]) + dataSend = dataSend + 1 + + if args.start_freq != None: + sendSerialData([CC_CMD_SET_START_FREQ, + (args.start_freq & 0xff000000) >> 24, + (args.start_freq & 0x00ff0000) >> 16, + (args.start_freq & 0x0000ff00) >> 8, + (args.start_freq & 0x000000ff)]) + dataSend = dataSend + 1 + + if args.end_freq != None: + sendSerialData([CC_CMD_SET_END_FREQ, + (args.end_freq & 0xff000000) >> 24, + (args.end_freq & 0x00ff0000) >> 16, + (args.end_freq & 0x0000ff00) >> 8, + (args.end_freq & 0x000000ff)]) + dataSend = dataSend + 1 + + if args.step_freq != None: + sendSerialData([CC_CMD_SET_FREQ_STEP, + (args.step_freq & 0xff000000) >> 24, + (args.step_freq & 0x00ff0000) >> 16, + (args.step_freq & 0x0000ff00) >> 8, + (args.step_freq & 0x000000ff)]) + dataSend = dataSend + 1 + + if args.intervall != None: + sendSerialData([CC_CMD_SET_INTERVALL, + (args.intervall & 0x0000ff00) >> 8, + (args.intervall & 0x000000ff)]) + dataSend = dataSend + 1 + + if args.drive_str != None: + sendSerialData([CC_CMD_SET_DRIVE_STRENGTH, + args.drive_str]) + dataSend = dataSend + 1 + + if args.start_meas == True: + sendSerialData([CC_CMD_START_MEASUREMENT]) + dataSend = dataSend + 1 + + # 4. start main loop + while dataSend > 0 and timeout < TIMEOUT_CNT_MAX: + + thread_lock.acquire() + tmp_messages = copy.deepcopy(cc_received_messages) + thread_lock.release() + + # 4.1 test for the response(s) + for e in tmp_messages: + if e[2] == False: # test for unread message + + print "1>>" + str(dataSend) + + # process it and set the data to read + if e[1] == MSG_TYPE_ANSWER_OK: + print "recv: OK" + + elif e[1] == MSG_TYPE_ANSWER_NOK: + print "recv: NOT OK" + + elif e[1] == MSG_TYPE_MEAS_FREQ_INFO_: + print "recv: FREQ INFO" + freq = e[3][0] << 24 + freq += e[3][1] << 16 + freq += e[3][2] << 8 + freq += e[3][3] + a0 = e[3][4] << 8 + a0 += e[3][5] + a1 = e[3][6] << 8 + a1 += e[3][7] + + elif e[1] == MSG_TYPE_CONFIG: + print "recv: CONFIG" + start_freq = e[3][0] << 24 + start_freq += e[3][1] << 16 + start_freq += e[3][2] << 8 + start_freq += e[3][3] + end_freq = e[3][4] << 24 + end_freq += e[3][5] << 16 + end_freq += e[3][6] << 8 + end_freq += e[3][7] + step_freq = e[3][8] << 24 + step_freq += e[3][9] << 16 + step_freq += e[3][10] << 8 + step_freq += e[3][11] + intervall = e[3][12] << 8 + intervall += e[3][13] + drive_str = e[3][14] + print "start_freq = " + str(start_freq) + print "end_freq = " + str(end_freq) + print "step_freq = " + str(step_freq) + print "intervall = " + str(intervall) + print "drive_str = " + str(drive_str) + + elif e[1] == MSG_TYPE_MEAS_END_INFO: + print "recv: END INFO" + + if args.output_file != None: + pass # TODO impl + if args.show_graph == True: + pass # TODO impl + + else: + print "err: unknown type 0x%02x" % (e[1]) + break + + thread_lock.acquire() + cc_received_messages[e[0]][2] = True + thread_lock.release() + + timeout = 0 # reset the timeout + + # reduce the number of messages to receive + dataSend = dataSend - 1 + + # manage the timeout behaviour + time.sleep(MAIN_LOOP_DELAY_S) + timeout = timeout + 1 + + if timeout >= TIMEOUT_CNT_MAX: + print "Timeout happened" + + # 5. stop data processing thread + cc_stopReceiverThread() + + # 6. close serial device + closeSerialDevice() + + exit(0) +