Hybrid Testing of a Solar Tracking Equipment using In-Circuit Testing and JTAG Debugging Strategies

Eine interessante Sache an meiner Doktorarbeit „Powering and Evaluating Deep Learning-based Systems using Green Energy“ ist, dass sie 3 Hauptbereiche kombiniert: Deep Learning, grüne Energie sowie Hardware- und Software-Testing.

Wie Sie vorhin in meinem Blog gesehen haben, habe ich bereits über die Hard– und Software-Testmethoden geschrieben, die bei unserem modifiziertem zweiachsigen Solar-Tracker nach dem Cast-Shadow-Prinzip angewandt werden. Sie haben auch den Blogpost über das kostengünstige FPICT-Gerät gesehen, das wir vorgeschlagen haben, um kleine PCBs zu testen. Was Sie nicht gesehen haben, ist, wie dieser FPICT verwendet werden kann, um unseren zweiachsigen Solar-Tracker zu testen. Dies ist das Thema des heutigen Blogposts.

Zusammen mit meinem ehemaligen Doktorandenkollegen Raul Rotar haben wir im Jahr 2020 beschlossen, diesen FPICT zusammen mit einer anderen Testmethode namens JTAG Boundary Scan zu verwenden, um neue Arten von Fehlern zu entdecken, die während des normalen Betriebs auftreten können. Die Forschungsarbeit trägt den Titel „Hybrid Testing of a Solar Tracking Equipment using In-Circuit Testing and JTAG Debugging Strategies„und wurde schon früher in unseren Forschungsartikel „Improving the Solar Reliability Factor of a Dual-Axis Solar Tracking System using Energy-Efficient Testing Solutions“ genannt.

Ich erinnere mich, dass wir diese Forschungsarbeit letztes Jahr ein paar Tage nach der Verteidigung meiner Doktorarbeit fertiggestellt haben, aber bis jetzt keine Zeit hatten, sie zu präsentieren.

Dieses Forschungspapier wird heute auf der 2021 IEEE International Conference on Environment and Electrical Engineering (EEEIC) in Bari, Italien, vorgestellt.

Zusammenfassung: Dieses Papier stellt einen Echtzeit-Hardware-Testentwurf vor, der auf einem hybriden Ansatz zwischen Flying-Probe-inspirierten In-Circuit-Tests (FPICT) und Debugging-Techniken der Joint Test Action Group (JTAG) basiert. Der FPICT wird zum Testen der physikalischen Parameterwerte unserer zweiachsigen Solar-Nachführungsausrüstung verwendet, die aus 1× Optokoppler, 1× Arduino UNO-Board und 2× L298N-Motortreibern besteht. Aufgrund der nicht vorhandenen JTAG-Testeinrichtungen des Arduino UNO-Boards haben wir es durch ein STM32-Entwicklungsboard ersetzt. Um Zugriff auf die interne Logik des STM32-Mikrocontrollers zu erhalten, haben wir einen dedizierten und kostengünstigen ST-Link V2-JTAG-Adapter an den FPICT-Baustein angeschlossen. Um dem FPICT-Baustein alle 5 Circuits Under Tests (CUTs) Testpunkte (TPs) zugänglicher zu machen, entwarfen wir zusätzlich eine kundenspezifische modulare Leiterplatte (PCB). Schließlich stellen wir ein autonomes Design vor, das die Selbstversorgung hinsichtlich des Energiebedarfs für die vorgeschlagene hybride Testmethode sowie für die gesamte solare Nachführeinrichtung durch vollständige Nutzung der Sonnenenergie erreicht. Die experimentellen Ergebnisse zeigen, dass der vorgeschlagene nicht-intrusive Hybrid-Testansatz hinsichtlich der globalen Fehlerabdeckung (66,35% für alle angepeilten Fehler), der Platzierungsgenauigkeit (100% für berücksichtigte Testfälle), der Testzeit und der Kosten effizient ist.

Sie können den Forschungsartikel hier lesen.

Hier habe ich alle Projektdateien bezüglich unserer Hybrid-Test einer Solar-Nachführanlage mit In-Circuit-Test und JTAG-Debugging-Strategien veröffentlicht.

manual_bs.tcl

/*
* Author: Sorin Liviu Jurj
* This code is part of a paper called „Hybrid Testing of a Solar Tracking Equipment using In-Circuit Testing and JTAG Debugging Strategies“. More information about the paper you can find here: https://jurj.de/hybrid-testing-of-a-solar-tracking-equipment-using-in-circuit-testing-and-jtag-debugging-strategies
*
*/

# Init global variables to work with the boundary scan register
# the first argument is tap name, the second is BSR length
proc init_bs {tap len} {
global bsrtap bsrlen
set bsrtap $tap
set bsrlen $len
init_bsrstate
# disable polling for the cpu TAP as it should be kept in BYPASS
poll off
sample_mode
}

# In this mode BSR doesn’t control the outputs but can read the current
# pins‘ states, the CPU can continue to function normally
proc sample_mode {} {
global bsrtap
# SAMPLE/PRELOAD
scan $bsrtap 2
}

# Connect BSR to the boundary scan logic
proc extest_mode {} {
global bsrtap
# EXTEST
scan $bsrtap 0
}

# Write bsrstateout to target and store the result in bsrstate
proc exchange_bsr {} {
global bsrtap bsrstate bsrstateout
update_bsrstate [eval scan [concat $bsrtap $bsrstateout]]
return $bsrstate
}

# Check if particular bit is set in bsrstate
proc get_bit_bsr {bit} {
global bsrstate
set idx [expr $bit / 32]
set bit [expr $bit % 32]
expr ([lindex $bsrstate [expr $idx*2 + 1]] & [expr 2**$bit]) != 0
}

# Resample and get bit
proc sample_get_bit_bsr {bit} {
exchange_bsr
get_bit_bsr $bit
}

# Set particular bit to „value“ in bsrstateout
proc set_bit_bsr {bit value} {
global bsrstateout
set idx [expr ($bit / 32) * 2 + 1]
set bit [expr $bit % 32]
set bitval [expr 2**$bit]
set word [lindex $bsrstateout $idx]
if {$value == 0} {
set word [format %X [expr $word & ~$bitval]]
} else {
set word [format %X [expr $word | $bitval]]
}
set bsrstateout [lreplace $bsrstateout $idx $idx 0x$word]
return
}

# Set the bit and update BSR on target
proc set_bit_bsr_do {bit value} {
set_bit_bsr $bit $value
exchange_bsr
}

proc init_bsrstate {} {
global bsrtap bsrlen bsrstate bsrstateout
set bsrstate „“
for {set i $bsrlen} {$i > 32} {incr i -32} {
append bsrstate 32 “ “ 0xFFFFFFFF “ “
}
if {$i > 0} {
append bsrstate $i “ “ 0xFFFFFFFF
}
set bsrstateout $bsrstate
return
}

proc update_bsrstate {state} {
global bsrstate
set i 1
foreach word $state {
set bsrstate [lreplace $bsrstate $i $i 0x$word]
incr i 2
}
}

main.py

/*
* Author: Sorin Liviu Jurj
* This code is part of a paper called „Hybrid Testing of a Solar Tracking Equipment using In-Circuit Testing and JTAG Debugging Strategies“. More information about the paper you can find here: https://jurj.de/hybrid-testing-of-a-solar-tracking-equipment-using-in-circuit-testing-and-jtag-debugging-strategies
*
*/
# This is a sample Python script to launch the hybrid testing for solar tracker
import serial
import os
import time
import telnetlib

if __name__ == ‚__main__‘:
print(‚Welcome to Hybrid Testing system. please select an appropriate choice\na) Boundary Scan Test\nb) FPICT (Flying Probe In-Circuit Tester\nc) Hybrid Testing‘)
in_user= input(„Enter your choice:“)
if str(in_user) == ‚b‘:
ser1 = serial.Serial(‚COM8‘, 9600)
ser1.write(‚BD‘)
if str(in_user) == ‚a‘:
#os.system(‚cmd /k „date“‚)
os.system(‚cmd /k „\“D:\OpenOCD-20200729-0.10.0\bin\openocd\“ -f \“D:\\OpenOCD-20200729-0.10.0\\share\\openocd\\scripts\\interface\\busblaster.cfg\“ -f \“D:\\OpenOCD-20200729-0.10.0\\share\\openocd\\scripts\\target\\stm32f0x.cfg\“ -f \“D:\\OpenOCD-20200729-0.10.0\\share\\openocd\\scripts\\manual_bs.tcl\“‚)
time.sleep(0.5)
os.system(‚cmd /k „dism /online /Enable-Feature /FeatureName:TelnetClient“‚)
time.sleep(0.5)
os.system(‚cmd /k „telnet 127.0.0.1 4444″‚)
time.sleep(0.1)
HOST = „127.0.0.1“
tn = telnetlib.Telnet(HOST)
tn.write(„init\n“)
time.sleep(0.1)
tn.write(„source \share\openocd\scripts\manual_bs.tcl\n“)
time.sleep(0.1)
tn.write(„init_bs stm32f0x.bs 406\n“)
time.sleep(0.1)
tn.write(„extest_mode\n“)
time.sleep(0.1)
tn.write(„exchange_bsr\n“)
time.sleep(0.1)
tn.write(„echo \“All LEDs should be OFF, press Enter\“\n“)
time.sleep(0.1)
tn.write(„read stdin 1\n“)
time.sleep(0.1)
tn.write(„set_bit_bsr 125 0\n“)
time.sleep(0.1)
tn.write(„set_bit_bsr_do 124 1\n“)
time.sleep(0.1)
tn.write(„echo \“Green LED should be ON, blue LED OFF, press Enter\“\n“)
time.sleep(0.1)
tn.write(„read stdin 1\n“)
#Add furthers ports as needed
if str(in_user) == ‚c‘:
# os.system(‚cmd /k „date“‚)
os.system(‚cmd /k „\“D:\OpenOCD-20200729-0.10.0\bin\openocd\“ -f \“D:\\OpenOCD-20200729-0.10.0\\share\\openocd\\scripts\\interface\\busblaster.cfg\“ -f \“D:\\OpenOCD-20200729-0.10.0\\share\\openocd\\scripts\\target\\stm32f0x.cfg\“ -f \“D:\\OpenOCD-20200729-0.10.0\\share\\openocd\\scripts\\manual_bs.tcl\“‚)
time.sleep(0.5)
os.system(‚cmd /k „dism /online /Enable-Feature /FeatureName:TelnetClient“‚)
time.sleep(0.5)
os.system(‚cmd /k „telnet 127.0.0.1 4444″‚)
time.sleep(0.1)
HOST = „127.0.0.1“
tn = telnetlib.Telnet(HOST)
tn.write(„init\n“)
time.sleep(0.1)
tn.write(„source \share\openocd\scripts\manual_bs.tcl\n“)
time.sleep(0.1)
tn.write(„init_bs stm32f0x.bs 406\n“)
time.sleep(0.1)
tn.write(„extest_mode\n“)
time.sleep(0.1)
tn.write(„exchange_bsr\n“)
time.sleep(0.1)
tn.write(„echo \“All LEDs should be OFF, press Enter\“\n“)
time.sleep(0.1)
tn.write(„read stdin 1\n“)
time.sleep(0.1)
tn.write(„set_bit_bsr 125 0\n“)
time.sleep(0.1)
tn.write(„set_bit_bsr_do 124 1\n“)
time.sleep(0.1)
tn.write(„echo \“Green LED should be ON, blue LED OFF, press Enter\“\n“)
time.sleep(0.1)
tn.write(„read stdin 1\n“)

#——————-Do not go below this line————————–
ser1 = serial.Serial(‚COM8‘, 9600)
ser1.write(‚BD‘)

Solar_Tracker_Code.ino

/*
* Author: Sorin Liviu Jurj
* This code is part of a paper called „Hybrid Testing of a Solar Tracking Equipment using In-Circuit Testing and JTAG Debugging Strategies“. More information about the paper you can find here: https://jurj.de/hybrid-testing-of-a-solar-tracking-equipment-using-in-circuit-testing-and-jtag-debugging-strategies
*
*/
// Solar Tracker Active Tracking Code – Updated Version
#include <Stepper.h> //Integrating library for dealing Stepper.h stepper motors
#include <math.h> //Integrating design math.h library for basic mathematical operations
//Declaring Constants
#define motorStephor 200 //steps for horizontal motor
#define motorStepver 200 //steps for vertical motor
//Digital pins
#define motor1hor 4
#define motor2hor 5
#define motor3hor 6
#define motor4hor 7
#define motor1ver 8
#define motor2ver 9
#define motor3ver 10
#define motor4ver 11
//Variables
int average; //Average of four LDR
int h=60; //Steps executed by the horizontal motor
int v=5; //Steps executed by the vertical motor
int ltsensor; //Value of the top left LDR
int rtsensor; //Value of the top right LDR
int rdsensor; //Value of the bottom right LDR
int ldsensor; //Value of the bottom left LDR
int sen=50; //Sensibility
int dil; //Average set of LDR left
int dit; //Average set of LDR top
int dir; //Average set of LDR right
int did; //Average set of LDR bottom
int diff; //Difference between LDR above the bottom
int diff2; //Difference between LDR left to right
int pup; //upper switch
int pdown; //lower switch

Stepper horStep (motorStephor, motor1hor, motor2hor, motor3hor, motor4hor);
Stepper verStep (motorStepver, motor1ver, motor2ver, motor3ver, motor4ver);
//Program initialization
void setup (){
horStep.setSpeed (30); //RPM horizontal motor
verStep.setSpeed (10); //RPM vertical motor
//Serial Port
Serial.begin(9600);
//Pins configuration
pinMode(ltsensor, INPUT);
pinMode(rtsensor, INPUT);
pinMode(ldsensor, INPUT);
pinMode(rdsensor, INPUT);
pinMode(pup, INPUT);
pinMode(pdown, INPUT);
}
String str ;

void loop (){

do{
ltsensor = analogRead(1)*1.022; //(constant is to calibrate the LDR)
rtsensor = analogRead(2)*1.007;
ldsensor = analogRead(3);
rdsensor = analogRead(4)*1.013;
pup = digitalRead (2); //Reading switches
pdown = digitalRead(3);
average = (ltsensor + ldsensor + rtsensor + rdsensor)/4; //Average LDR
dit = (ltsensor + rtsensor)/2; //Average sensors up
did = (ldsensor + rdsensor)/2; //Average sensors down
diff = (dit – did); //Difference between the level of radiation
delay (50);
if ((pup==HIGH)&&(average<=8)|| (pdown==HIGH)&&(average<=8)) //If the value of the average of the sensors is equal or less than 8 and the switches have the range
mov(); //mov function

if(Serial.available()>0){
str = Serial.readString();
if (str == ‚BD‘){
// Test cases to trigger the flying the probe
if ((pup==HIGH)&&(average>=8)|| (pdown==HIGH)&&(average>=8)){
Serial.write(„START“);
}
if ((pup==LOW)&&(average>=255)|| (pdown==LOW)&&(average>=255)){
Serial.write(„START“);
}
if ((pup==LOW)&&(average>=512)|| (pdown==LOW)&&(average>=512)){
Serial.write(„START“);
}
if ((pup==LOW)&&(average>=755)|| (pdown==LOW)&&(average>=755)){
Serial.write(„START“);
}

if ((pup==LOW)&&(average>=755)|| (pdown==HIGH)&&(average>=755)){
Serial.write(„START“);
}

if ((pup==HIGH)&&(average>=755)|| (pdown==LOW)&&(average>=755)){
Serial.write(„START“);
}
if ((pup==HIGH)&&(average>=755)|| (pdown==LOW)&&(average>=755)){
Serial.write(„START“);
}
if ((pup==HIGH)&&(average>=1000)|| (pdown==LOW)&&(average>=1000)){
Serial.write(„START“);
}
if ((pup==LOW)&&(average>=1000)|| (pdown==HIGH)&&(average>=1000)){
Serial.write(„START“);
}
}
}
}
while ((pup==HIGH)&&(average<=8)||(pdown==HIGH)&&(average<=8));
if (-1*sen > diff || diff > sen){ //If the measured difference between the set of sensors is greater or less than the sensitivity value

if(dit < did) //If the mean value of the above sensors is smaller than the bottom sensors
{
if (pdown==HIGH){
verStep.step (0); //Stop vertical motor

delay (10);

}
else
if (pdown==LOW){
verStep.step (v); //Turn motor up
delay (50);
}
}

else if(dit > did){ //If the average value of bottom sensors is smaller than the above sensors
if (pup==HIGH){
verStep.step (0); //Stop vertical motor
delay (10);
}

else if (pup==LOW){
verStep.step (-v); //Turn motor down
delay (50);
}
}

else{ //any other case
verStep.step (0); //Stop vertical motor
delay (10);
}
}

delay (10);
ltsensor = analogRead(1)*1.022; //(constant is to calibrate the LDR)
rtsensor = analogRead(2)*1.007;
ldsensor = analogRead(3);
rdsensor= analogRead(4)*1.013;
dil = (ltsensor + ldsensor)/2; //Average sensors left
dir = (rtsensor + rdsensor)/2; //Average sensors right
diff2 = (dil – dir); //Difference between the level of radiation
delay (50);
if (-1*sen > diff2 || diff2 > sen){ //If the measured difference between the set of sensors is greater or less than the sensitivity value
if(dil < dir){ //If the average of the left sensor is smaller than the right sensor
horStep.step (h); //Turn motor right
delay (10);
}
else
if(dil > dir){ //If the average of the left sensor is larger than the right sensor
horStep.step (-h); //Turn motor left
delay (10);
}
else{ //any other case
horStep.step (0); //Stop horizontal motor
delay (10);
}
}
delay(10);
}
// “mov function”
void mov (){
if (pup==HIGH){
verStep.step (72); //Turn 72 steps up (are the steps to change position once hide the sun)
delay (50);
}
else if (pdown==HIGH)
{
verStep.step (-72); //Turn 72 steps down
delay (50);
}
delay (10);
}

Flying_Probe_Code.ino

/*
* Author: Sorin Liviu Jurj
* This code is part of a paper called „Hybrid Testing of a Solar Tracking Equipment using In-Circuit Testing and JTAG Debugging Strategies“. More information about the paper you can find here: https://jurj.de/hybrid-testing-of-a-solar-tracking-equipment-using-in-circuit-testing-and-jtag-debugging-strategies
*
*/
// Flying Probe In Circuit Tester
#include <Stepper.h>

#define STEPS_PER_REVOLUTION 2048 //steps takes for the stepper motor for one complete revolution (refer stepper motor manual/doc)
#define MOTOR_SPEED1 15 //speed of motor X
#define MOTOR_SPEED2 15 //speed of motor Y
#define MOTOR_SPEED3 13 //speed of motor Z
#define MM_PER_STEP 0.10 //mm the arm moves for one step of stepper (do trial and run testing for finding this value) initial 7
#define TOTAL_VOLTAGE_PARAMS 5 //total number of voltage parameters to be tested
#define TOTAL_CURRENT_PARAMS 0 //total number of current parameters to be tested
#define RES_CUR_MEASURE 100 //Resistance in ohms between test points for Current measurement
#define STEPS_PER_MM 100 // This is an average value, not completely accurate

/*ENUM to configure stepper directiobn*/
typedef enum{
STEPPER_MOVE_FORWARD,
STEPPER_MOVE_BACKWARD,
}Stepper_Dir_t;

/*
configuration structure declaration for checking voltage
*/
typedef const struct {
int Dist_X_mm; //X distance in mm from reference point to test point
int Dist_Y_mm; //Y distance in mm from reference point to test point
int Dist_Z_mm; //Z distance in mm from reference point to test point
float volExpectedL; //expected voltage lower value in volts
float volExpectedH; //expected voltage higher value in volts
char param[25]; //parameter description
}configStruct_vol;

/*
configuration structure final with exact steps and counts from mm and voltage value
*/
typedef struct {
int Dist_X_step; //no of steps for motor to reach test point from reference point – X
int Dist_Y_step; //no of steps for motor to reach test point from reference point – Y
int Dist_Z_step; //no of steps for motor to reach test point from reference point – Z
int CountExpectedL; //expected voltage lower value in count
int CountExpectedH; //expected voltage higher value in count
}configFinalStructVol_t;

/*
configuration structure declaration for checking current
*/
typedef const struct {
int Dist_X1_mm; //X distance in mm from reference point to first test point
int Dist_Y1_mm; //Y distance in mm from reference point to first test point
int Dist_X2_mm; //X distance in mm from reference point to second test point
int Dist_Y2_mm; //Y distance in mm from reference point to second test point
int Dist_Z_mm; //Z distance in mm from reference point to test point
int curExpectedL; //expected current lower value in milliamps
int curExpectedH; //expected current higher value in milliamps
char param[25]; //parameter description
}configStruct_cur;

/*
configuration structure final with exact steps and counts from mm and current value
*/
typedef struct {
int Dist_X1_step; //no of steps for motor to reach first test point from reference point – X
int Dist_Y1_step; //no of steps for motor to reach first test point from reference point – Y
int Dist_X2_step; //no of steps for motor to reach second test point from reference point – X
int Dist_Y2_step; //no of steps for motor to reach second test point from reference point – Y
int Dist_Z_step; //no of steps for motor to reach test point from reference point – Z
}configFinalStructCur_t;

/*
configuration structure for each params for voltage measurement
User should configure this structure
*/

configStruct_vol myConfigStruct_vol[TOTAL_VOLTAGE_PARAMS] = {
{16.98,11.95,15,4.5,5.0,“param1″}, //Pinul 7 – cu o valoare standard de 5V – Atmega328
{19.99,8.0,15,4.5,5.0,“param2″}, //Pinul 20 – cu o valoare standard de 5V – Atmega328
{19.96,8.0,15,4.5,5.0,“param3″}, //Pinul 21 – cu o valoare standard de 5V – Atmega328
{36.90,17.95,15,4.5,5.0,“param4″}, //Pinul 31 – cu o valoare standard de 5V – Atmega16u2
{38.02,18.60,15,4.5,5.0,“param5″}, //Pinul 32 – cu o valoare standard de 5V – Atmega16u2
};

/*
configuration structure for each params for current measurement
User should configure this structure

SW should check voltage on test point 1 and 2 and find the drop across the resister(user configured) between these two points
to find the current through the path
*/
configStruct_cur myConfigStruct_cur[TOTAL_CURRENT_PARAMS] = {
//{20,20,30,20,20,30,23,“param6″}, // ex: test point1 – (50,60,40) , test point2 – (30,10,40) , expected current range 15-23 mA
//{20,20,30,20,20,30,25,“param7″},
//{20,20,30,25,20,30,25,“param8″},
//{20,20,30,25,20,30,25,“param9″},
};

configFinalStructVol_t configFinalStructVol[TOTAL_VOLTAGE_PARAMS]; //structure for storing test point info (steps and count) for voltage
configFinalStructCur_t configFinalStructCur[TOTAL_CURRENT_PARAMS]; //structure for storing test point info in steps for current

/*stepper motors initialised

IO pins used for stepper motors
X – 22,23,24,25
Y – 26,27,28,29
Z – 30,31,32,33
*/

Stepper stepperX(STEPS_PER_REVOLUTION, 22, 23, 24, 25);
Stepper stepperY(STEPS_PER_REVOLUTION, 26, 27, 28, 29);
Stepper stepperZ(STEPS_PER_REVOLUTION, 30, 31, 32, 33);

int i;
// End point object
class endpoint_t{
uint8_t pin;
Stepper* stepper;

public:
endpoint_t(int p, Stepper* mystepper): pin(p), stepper(mystepper) {} ;

void to_endpoint(void){
//Serial.println(„Starting endpoint localization …“);
while(digitalRead(pin)){ // move until we have reached the endpoint
stepper->step(-100);
}
//Serial.println(„Localization complete …“);
}
};

#define x_endpoint 46 // pin definitions
#define y_endpoint 47
#define z_endpoint 48

endpoint_t* x_axis_endpoint; // define endpoints
endpoint_t* y_axis_endpoint;
endpoint_t* z_axis_endpoint;

void setup() {
//Initialise serial
Serial.begin(9600);
while(!Serial);

// set speed of stepper motors
stepperX.setSpeed(MOTOR_SPEED1);
stepperY.setSpeed(MOTOR_SPEED2);
stepperZ.setSpeed(MOTOR_SPEED3);

x_axis_endpoint = new endpoint_t(x_endpoint, &stepperX);
y_axis_endpoint = new endpoint_t(y_endpoint, &stepperY);
z_axis_endpoint = new endpoint_t(z_endpoint, &stepperZ);

toReferencePoint();
//convert arm movement distance to steps and voltage to count

Serial.println(„Converting distances to steps: „);
for (i = 0; i < TOTAL_VOLTAGE_PARAMS ; i ++){
configFinalStructVol[i].Dist_X_step = (myConfigStruct_vol[i].Dist_X_mm) * STEPS_PER_MM;
configFinalStructVol[i].Dist_Y_step = (myConfigStruct_vol[i].Dist_Y_mm) * STEPS_PER_MM;
configFinalStructVol[i].Dist_Z_step = (myConfigStruct_vol[i].Dist_Z_mm) * STEPS_PER_MM;
configFinalStructVol[i].CountExpectedL = (1023 * (myConfigStruct_vol[i].volExpectedL)) / 5;
configFinalStructVol[i].CountExpectedH = (1023 * (myConfigStruct_vol[i].volExpectedH)) / 5;

}

/*
convert arm movement distance to steps for tesing current at testing points
*/
for (i = 0; i < TOTAL_CURRENT_PARAMS ; i ++){
configFinalStructCur[i].Dist_X1_step = (myConfigStruct_cur[i].Dist_X1_mm) * STEPS_PER_MM;
configFinalStructCur[i].Dist_Y1_step = (myConfigStruct_cur[i].Dist_Y1_mm) * STEPS_PER_MM;
configFinalStructCur[i].Dist_X2_step = (myConfigStruct_cur[i].Dist_X2_mm) * STEPS_PER_MM;
configFinalStructCur[i].Dist_Y2_step = (myConfigStruct_cur[i].Dist_Y2_mm) * STEPS_PER_MM;
configFinalStructCur[i].Dist_Z_step = (myConfigStruct_cur[i].Dist_Z_mm) * STEPS_PER_MM;
}

Serial.println(„Setup complete.“);
}

String str ;
String startstr = String(„START“) ;

int count ;
float voltage1,voltage2;
int cur_mA;

void loop() {

/*check if user inputs via serial*/
if(Serial.available()>0){
str = Serial.readString();

/*check if user inputs START via serial*/
if(str.equals(startstr))
{
Serial.println(„STARTING UP….“);

for (i = 0; i < TOTAL_VOLTAGE_PARAMS ; i ++){
Serial.print(myConfigStruct_vol[i].param);

/*locate the arm to pogo pin position from reference point*/
stepperMove(
configFinalStructVol[i].Dist_X_step,
configFinalStructVol[i].Dist_Y_step,
configFinalStructVol[i].Dist_Z_step,
STEPPER_MOVE_FORWARD,
STEPPER_MOVE_FORWARD,
STEPPER_MOVE_FORWARD
);
delay(500);

/*read the analog value from the test point*/
count = analogRead(A0);
delay(1000); // delay before we start retracting probe

/*retract arm to reference point*/
toReferencePoint();
delay(50);

/*checks if the voltage is beyond expected range*/
if((count < configFinalStructVol[i].CountExpectedL) || (count > configFinalStructVol[i].CountExpectedH)){
Serial.println(“ : FAILED“);
//continue;
}
else{
Serial.println(“ : SUCCESS“);
}
Serial.println(„finished parameter: “ + String(i));
}

/*
check if voltage values tested successfully at test points
*/
if(i == TOTAL_VOLTAGE_PARAMS){

/*Current values testing on the test points*/
for (i = 0; i < TOTAL_CURRENT_PARAMS ; i ++){

Serial.print(myConfigStruct_cur[i].param);

/*locate the arm to test point 1 from reference point*/
stepperMove(configFinalStructCur[i].Dist_X1_step,configFinalStructCur[i].Dist_Y1_step,configFinalStructCur[i].Dist_Z_step,STEPPER_MOVE_FORWARD);
delay(10);

/*read the voltage value from the test point*/
voltage1 = (float)(analogRead(A0) * 5) / 1023;

/*retract arm to reference point*/
stepperMove(configFinalStructCur[i].Dist_X1_step,configFinalStructCur[i].Dist_Y1_step,configFinalStructCur[i].Dist_Z_step,STEPPER_MOVE_BACKWARD);
delay(10);

/*locate the arm to test point 2 from reference point*/
stepperMove(configFinalStructCur[i].Dist_X2_step,configFinalStructCur[i].Dist_Y2_step,configFinalStructCur[i].Dist_Z_step,STEPPER_MOVE_FORWARD);
delay(10);

/*read the voltage value from the test point*/
voltage2 = (float)(analogRead(A0) * 5) / 1023;

/*retract arm to reference point*/
stepperMove(configFinalStructCur[i].Dist_X2_step,configFinalStructCur[i].Dist_Y2_step,configFinalStructCur[i].Dist_Z_step,STEPPER_MOVE_BACKWARD);
delay(10);

/*Find current across the resistor*/
cur_mA = ((voltage2 – voltage1)/RES_CUR_MEASURE)*1000;

/*checks if the current is beyond expected range*/
if((cur_mA < myConfigStruct_cur[i].curExpectedL) || (cur_mA > myConfigStruct_cur[i].curExpectedH)){
Serial.println(“ : FAILED“);
break;
}
else{
Serial.println(“ : SUCCESS“);
}
}

/*
check if voltage values tested successfully at test points
*/
if(i == TOTAL_CURRENT_PARAMS){
Serial.println(„FINAL TEST STATUS : SUCCESS“);
}
/*
ERROR in tesing current values
*/
else{
Serial.println(„FINAL TEST STATUS : FAILED“);
Serial.println(„ENTER START TO INITIALIZE.. „);
}
}
/*
ERROR in tesing voltage values
*/
else{
Serial.println(„FINAL TEST STATUS : FAILED“);
Serial.println(„ENTER START TO INITIALIZE.. „);
}

}else{
Serial.println(„INVALID COMMAND.. „);
}
}
}

/*
Funtion to Move stepper forward and backward
*/
void stepperMove(int x,int y, int z , Stepper_Dir_t xdir, Stepper_Dir_t ydir, Stepper_Dir_t zdir){
if(xdir == STEPPER_MOVE_FORWARD){
stepperX.step(x);
}else{
stepperX.step(-x);
}

if(ydir == STEPPER_MOVE_FORWARD){
stepperY.step(y);
}else{
stepperY.step(-y);
}

delay(2000);
if(zdir == STEPPER_MOVE_FORWARD){
stepperZ.step(z);
}else{
stepperZ.step(-z);
}
}

void stepperMove(int x,int y, int z , Stepper_Dir_t dir){
switch (dir){
case STEPPER_MOVE_FORWARD:
stepperX.step(x);
stepperY.step(y);
stepperZ.step(z);
break;

case STEPPER_MOVE_BACKWARD:
stepperZ.step(-z);
stepperY.step(-y);
stepperX.step(-x);
break;

default:
break;
}
}

/*
* Function that returns probe to reference point
*/
void toReferencePoint(){
z_axis_endpoint->to_endpoint();
x_axis_endpoint->to_endpoint();
y_axis_endpoint->to_endpoint();

}

Leave a Comment

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie mehr darüber, wie Ihre Kommentardaten verarbeitet werden .