[PYTHON] Test automation starting with L-Chika (3) Oscilloscope integration

1.First of all

This is the third test automation series starting with L Chika.

Considering the recent energy saving situation, the lighting method of the LED to be tested is changed from [Static lighting](https://www.google.co.jp/search?hl=ja&as_q=Static lighting) to [Dynamic lighting](https: / /www.google.co.jp/search?hl=ja&as_q=dynamic lighting) will be changed. Therefore, we will modify the test bench so that the LED lighting voltage and lighting frequency can be measured with an oscilloscope and Go / No-Go judgment can be performed automatically.

IMG_0603s.jpg

Please see here for the articles so far.

  1. Test automation starting with L Chika
  2. Test automation starting with L-Chika (2) Improving maintainability of test scripts

2. Repair of test target

Change from static lighting to dynamic lighting with 1000Hz and duty ratio of 50%. tone (), [noTone ()](https://www.arduino.cc/reference/ On / off is controlled by en / language / functions / advanced-io / notone /).

ArduinoLedLight.ino(Change part)


void Led::on(void)
{
    //digitalWrite(m_led_pin, HIGH);
    tone(m_led_pin, 1000);
}

void Led::off(void)
{
    //digitalWrite(m_led_pin, LOW);
    noTone(m_led_pin);
}

3. Repair of test runner

--Add the following command.

|command|argument|function |-----------+----------------+---- |open_dso |None|-Import PyVISA and open the oscilloscope |dso |VISA command|・ Send and receive commands to and from the oscilloscope
・ Included in received data","Is"-"Replace with |eval_dbl_eq|Expected value(double type[^1])|・変数valがExpected valueの値(double type)Equal to |eval_dbl_gt|Standard value(double type)|・変数valがStandard value(double type)Evaluate if greater than |eval_dbl_lt|Standard value(double type)|・変数valがStandard value(double type)Evaluate if smaller

-Please install PyVISA [^ 2]. --Assuming that there is only one VISA device on the USB bus, use the device that can be opened first from the device list.

test-runner.py


#!/usr/bin/python3

#
# This software includes the work that is distributed in the Apache License 2.0
#

from time import sleep
import serial
import codecs
import csv
import sys
import visa

UNINITIALIZED = 0xdeadbeef

def serial_write(h, string):
    if h == UNINITIALIZED:
        print("UART Not Initialized.")
        return False
    else:
        string = string + '\n'
        string = str.encode(string)
        h.write(string)
        return True


def open_dso():
    rm = visa.ResourceManager()
    resources = rm.list_resources()
    #print(resources)
    for resource in resources:
        #print(resource)
        try:
            dso = rm.open_resource(resource)
        except:
            print(resource, "Not Found.")
        else:
            print(resource, "Detected.")
            return dso

    #Throw an error to caller if none succeed.
    return dso


def main():
    is_passed = True
    val = str(UNINITIALIZED)
    dso = UNINITIALIZED
    uart = UNINITIALIZED
    arg = [""]

    with codecs.open('script.csv', 'r', 'utf-8') as file:
        script = csv.reader(file, delimiter=',', lineterminator='\r\n', quotechar='"')

        with codecs.open('result.csv', 'w', 'utf-8') as file:
            result = csv.writer(file, delimiter=',', lineterminator='\r\n', quotechar='"')

            for cmd in script:
                print(cmd)

                if "#" in cmd[0]:
                    pass

                elif cmd[0]=="sleep":
                    sleep(float(cmd[1]))
                    cmd.append("OK")

                elif cmd[0]=="open_dso":
                    try:
                        dso = open_dso()
                    except:
                        cmd.append("NG")
                        is_passed = False
                    else:
                        cmd.append("OK")

                elif cmd[0]=="dso":
                    try:
                        if "?" in cmd[1]:
                            val = dso.query(cmd[1]).rstrip().replace(",", "-")
                            cmd.append(val)
                        else:
                            dso.write(cmd[1])
                            cmd.append("OK")
                    except:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="open_uart":
                    try:
                        uart = serial.Serial(cmd[1], 115200, timeout=1.0, dsrdtr=1)
                        cmd.append("OK")
                    except:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="send":
                    ret = serial_write(uart, cmd[1])
                    if ret == True:
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="rcvd":
                    try:
                        val = uart.readline().strip().decode('utf-8')
                        cmd.append(val)
                        cmd.append("OK")
                    except:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_str_eq":
                    if str(val) == str(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_int_eq":
                    if int(val) == int(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_int_gt":
                    if int(val) > int(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_int_lt":
                    if int(val) < int(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_dbl_eq":
                    if float(val) == float(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_dbl_gt":
                    if float(val) > float(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                elif cmd[0]=="eval_dbl_lt":
                    if float(val) < float(cmd[1]):
                        cmd.append("OK")
                    else:
                        cmd.append("NG")
                        is_passed = False

                else:
                    cmd.append("#")

                print(cmd)
                result.writerow(cmd)

                if is_passed == False:
                    print("FAIL")
                    sys.exit(1)

    if is_passed == True:
        print("PASS")
        sys.exit(0)


main()

4. Test script and script generator

4.1 (single function) test script

Add the following test script to the script-parts folder.

--The VISA command is an example of a RIGOL oscilloscope. --Please match the character string of the model of setup_dso.csv to your model.

setup_dso.csv


#
# Setup DSO
open_dso,
dso,*IDN?
eval_str_eq,RIGOL TECHNOLOGIES-DS1104Z-XXXXXXXXXXXXXX-00.04.04.SP3

dso_write_timescale_200us.csv


#
# Timebase Scale 200us
dso,:TIMebase:SCALe 0.0002

dso_query_vmax_gt1700-lt1900.csv


#
# 1.80V +/- 0.10V
dso,:MEASure:VMAX? CHANnel1
eval_dbl_gt,1.70
eval_dbl_lt,1.90

dso_query_freq_gt995-lt1005.csv


#
# 1000Hz +/- 5Hz
dso,:MEASure:FREQuency? CHANnel1
eval_dbl_gt,995
eval_dbl_lt,1005

4.2 Script Generator

The following two points have been repaired.

--Added oscilloscope setup --Changed the check when the LED is lit to an oscilloscope

script-generator.bat


REM script generator for LED Light Test Bench

set script_parts_dir=script-parts
set script_file_name=script.csv

REM test bench setup
copy /b %script_parts_dir%\setup.csv %script_file_name%

REM digital oscilloscope setup
copy /b %script_file_name% + %script_parts_dir%\setup_dso.csv
copy /b %script_file_name% + %script_parts_dir%\dso_write_timescale_200us.csv

The REM LED is not lit(LED voltage is less than 200mV)
copy /b %script_file_name% + %script_parts_dir%\eval_int_lt0200.csv

Turn on the REM relay and
copy /b %script_file_name% + %script_parts_dir%\operation_relay_on.csv
REM 1.LED lighting voltage greater than 1700 mV and less than 1900 mV
copy /b %script_file_name% + %script_parts_dir%\dso_query_vmax_gt1700-lt1900.csv
REM 2.LED lighting frequency is greater than 995Hz and less than 1005Hz
copy /b %script_file_name% + %script_parts_dir%\dso_query_freq_gt995-lt1005.csv

Turn off the REM relay and the LED voltage is less than 200mV
copy /b %script_file_name% + %script_parts_dir%\operation_relay_off.csv
copy /b %script_file_name% + %script_parts_dir%\eval_int_lt0200.csv

5. Test execution result

result.csv


# setup
# wait for if restart Arduino Uno
sleep,2,OK
#
# Open UART
open_uart,COM3,OK
#
# model and version check
send,i,OK
rcvd,Arduino Test Bench Ver.100,OK
eval_str_eq,Arduino Test Bench Ver.100,OK
#
# relay assigned Pin number check
send,p,OK
rcvd,12,OK
eval_int_eq,12,OK
#
# Setup DSO
open_dso,,OK
dso,*IDN?,RIGOL TECHNOLOGIES-DS1104Z-XXXXXXXXXXXXXX-00.04.04.SP3
eval_str_eq,RIGOL TECHNOLOGIES-DS1104Z-XXXXXXXXXXXXXX-00.04.04.SP3,OK
#
# Timebase Scale 200us
dso,:TIMebase:SCALe 0.0002,OK
#
# eval_int_lt0200
send,v,OK
rcvd,0,OK
eval_int_lt,200,OK
#
# relay ON
send,n,OK
sleep,1,OK
#
# 1.80V +/- 0.10V
dso,:MEASure:VMAX? CHANnel1,1.840000e+00
eval_dbl_gt,1.70,OK
eval_dbl_lt,1.90,OK
#
# 1000Hz +/- 5Hz
dso,:MEASure:FREQuency? CHANnel1,9.999999e+02
eval_dbl_gt,995,OK
eval_dbl_lt,1005,OK
#
# relay OFF
send,f,OK
sleep,1,OK
#
# eval_int_lt0200
send,v,OK
rcvd,0,OK
eval_int_lt,200,OK

6. Conclusion

Go / No-Go judgment based on oscilloscope measurement results could be automated with Python \ (^ o ^) /

[^ 1]: Python float is a double precision floating point number, but in general, float is single precision and double is double precision, so it is written as double type here. [^ 2]: The official website provides installation instructions using the pip command. Also, the procedure I installed in the Miniconda environment with the conda command is [here](https://qiita.com/pbjpkas/items/bd483d4773468e26414c#22-python%E5%AE%9F%E8%A1%8C%E7% 92% B0% E5% A2% 83).

Recommended Posts

Test automation starting with L-Chika (3) Oscilloscope integration
Test automation starting with L-Chika (5) Webcam and OCR integration
Create an environment for test automation with AirtestIDE (Tips)
Primality test with Python
Strengthen with code test ⑦
Strengthen with code test ⑨
Strengthen with code test ③
Strengthen with code test ⑤
Primality test with python
Python starting with Windows 7
GRPC starting with Python
Strengthen with code test ②
python tag integration test
Strengthen with code test ①
Test automation for work
Strengthen with code test ⑧
Strengthen with code test ⑨
The true value of Terraform automation starting with Oracle Cloud