White-Box Testing Strategy for a Solar Tracking Device using NodeMcu Lua ESP8266 WiFi Network Development Board Module

Ich habe letzte Woche mein Forschungsartikel White-Box Testing Strategy for a Solar Tracking Device using NodeMcu Lua ESP8266 WiFi Network Development Board Module bei SIITME präsentiert.

Abstrakt: In diesem Dokument wird eine neuartige Technik zum Testen des Software-Codes eines Solar-Tracking-Geräts vorgestellt, indem ein White-Box-Testansatz implementiert wird, der ein Wi-Fi-Modul verwendet. Erstens gelingt es uns zu überprüfen, ob die drahtlose Datenübertragung, die die Bewegungen des Solar-Tracking-Geräts steuert, dem Softwarecode entspricht, der auf der Hauptsteuerplatine Arduino UNO ausgeführt wird. Zusätzlich zur lokalen Implementierung wird eine Cloud-basierte Lösung zusammen mit einer mobilen Anwendung zur Fernsteuerung, zum Testen und zur Kommunikation mit dem Solar-Tracking-Gerät vorgeschlagen. Zweitens haben wir White-Box-Testtechniken verwendet, um Softwarefehler in unserem Solar Tracker zu testen und Details zu geben. Wir haben sowohl Einheitentesttechniken als auch benutzerdefinierten Code implementiert, um alle Lücken und möglichen Haltepunkte in unserer Solar-Tracker-Software durch Untersuchung der Fehler in der Kommunikation, des Steuerungsflusses und der Fehlerbehandlung zu ermitteln. Die experimentellen Ergebnisse zeigen, dass unsere White-Box-Teststrategie unter den Gesichtspunkten der Fehlerabdeckung und der Kosten effizient ist.

Sie können den Artikel hier lesen: https://ieeexplore.ieee.org/document/8599250

Mein wissenschaftliches Posterdesign:

Der Code zu White-Box Testing Strategy for a Solar Tracking Device using NodeMcu Lua ESP8266 WiFi Network Development Board Module (Der Code umfasst 2 Codes, einen für Arduino UNO und einen Code für das ESP8266 Wi-Fi-Modul) kann unten eingesehen oder von hier heruntergeladen werden.

UNO Code:

/*
* Name: Solar Tracker EspCode.ino (test version)
* Author: Sorin Liviu Jurj
*
* Description:
* This software will implement different testing testing techniques to test
* the software functionality and features. We will tackle each part of the
* code individually and attempt to show all the possible break points and
* try to detect possible fault errors using white box testing techniques.
* This testing is based on the AUnit arduino library which is a port of
* ArduinoUnit and Google Test testing platforms.
*/

#include <Stepper.h>
#include <math.h>
#include <SoftwareSerial.h>

// Library for testing
#include <AUnit.h>
using aunit::TestRunner; // name space for aunit to prevent name clashing

/*
* Please uncomment FIELD MODE and comment TEST MODE in order to receive analog readings
*/
#define TEST_MODE 1
// #define FIELD_MODE 0

uint8_t motorStephor = 200, motorStepver = 200;
uint8_t motor1hor = 4, motor2hor = 5, motor3hor = 6, motor4hor = 7;
uint8_t motor1ver = 8, motor2ver = 9, motor3ver = 10, motor4ver = 11;

int average, h=20, v=5;
int ltsensor, rtsensor, rdsensor, ldsensor;
int sen=50;

int dil, dit, dir, did, diff, diff2;
int pup = 12, pdown = 13; //lower switch

// definitions of stepper motors
Stepper horStep (motorStephor, motor1hor, motor2hor, motor3hor, motor4hor);
Stepper verStep (motorStepver, motor1ver, motor2ver, motor3ver, motor4ver);

// serial communication with ESP
SoftwareSerial mySerial(2, 3); // RX, TX

//———————————————
//———————————————
// TESTS
//———————————————
//———————————————
/*
* We will run a continious test on the LTSensor,
* LDSensor, RTSensor, and RDSensor data values to
* make that they are within the specified range.
* This can be a source of error if the values are
* outside the specified range, as this can lead to
* errora and unpredictable movement of the stepper
* motors.
*/
testing(sensorData)
{
assertLessOrEqual(ltsensor, 1024);
assertLessOrEqual(rtsensor, 1024);
assertLessOrEqual(rdsensor, 1024);
assertLessOrEqual(ldsensor, 1024);
}

/*
* Main Program Setup
*/
void setup ()
{
/*
* The values for the intial speed of the stepper motors are hard coded, so there is little room for error.
* In a setup where they are selected dynamically, we will have to run a test to make sure that they are
* within a specified range.
*/
horStep.setSpeed (30);
verStep.setSpeed (10);

Serial.begin(9600);
mySerial.begin(9600);

/*
* This while statement make sure that the serial connection is completely setup and running before, we can
* continue. In some cases, the serial communication msy not start fast enough. This will lead to data
* corruption and error if we are trying to receive or send data when the serial connection is not yet completly
* ready.
*/
while (!Serial && !mySerial);

pinMode(pup, INPUT);
pinMode(pdown, INPUT);
}

// this is a long variable that holds the last time we set the sent analog data to the server. We use it to
// control the frequency of data transmission to the server. Sending that continously can lead to over tasking
// the server script that processed the received data, and can also cause framing errors in serial communication.
long lastSendTime = 0;
/*
* Main Program Loop
*/
void loop ()
{
// send data to server every 3 seconds
if(millis()-lastSendTime > 3000)
{
Data_Send();
lastSendTime = millis();
}

do
{
/*
* if the device is set in field mode we read control data form the ananlog sensors, But if it is
* operating in test mode (receiving control instructions from our mqtt server), we do not need to
* read data from analog sensors. This selection process is necessary to ensure that the data being
* used to control the motors is solely from one source.
*/
#ifdef FIELD_MODE
ltsensor = analogRead(1)*1.022;
rtsensor = analogRead(2)*1.007;
ldsensor = analogRead(3);
rdsensor = analogRead(4)*1.013;
#endif

#ifdef TEST_MODE
Receive_Data();
#endif
average= (ltsensor + ldsensor + rtsensor + rdsensor)/4;

dit = (ltsensor + rtsensor)/2;
did = (ldsensor + rdsensor)/2;
diff =(dit – did);
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

}

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);

#ifdef FIELD_MODE
ltsensor = analogRead(1)*1.022;
rtsensor = analogRead(2)*1.007;
ldsensor = analogRead(3);
rdsensor = analogRead(4)*1.013;
#endif

#ifdef TEST_MODE
Receive_Data();
#endif

dil = (ltsensor + ldsensor)/2;
dir = (rtsensor + rdsensor)/2;
diff2 = (dil – dir);
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);
}

/*
* Move 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);
}

void Data_Send()
{
// get data from sensors
int d1 = analogRead(1)*1.022;
int d2 = analogRead(2)*1.007;
int d3 = analogRead(3);
int d4 = analogRead(4)*1.013;

Serial.println(„Sending to ESP“);
mySerial.print(d1);
mySerial.print(‚.‘);
mySerial.print(d2);
mySerial.print(‚.‘);
mySerial.print(d3);
mySerial.print(‚.‘);
mySerial.print(d4);
mySerial.print(‚.‘);
mySerial.print(‚\r‘);
}

/*
* Function that receives data from the ESP.
* This is a possible breakpoint as errors can arise when using serial
* communication at higher speeds.. We have to run a test which will ensure that
* the values received are valid integers, and we can also check for the length of the received
* data since we are expecting a specific number of characters from the ESP.
*/
void Receive_Data()
{
if(mySerial.available())
{
String gh = „“;
gh = mySerial.readStringUntil(‚\r‘);

Serial.print(„Received Data from ESP: „);

ltsensor = getValue(gh, ‚.‘, 1).toInt();
rtsensor = getValue(gh, ‚.‘, 2).toInt();
ldsensor = getValue(gh, ‚.‘, 3).toInt();
rdsensor= getValue(gh, ‚.‘, 4).toInt();

Serial.print(gh); Serial.println();
return ;
}
}

/*
* Function that splits a string into oomponent strings
*/
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() – 1;

for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : „“;
}

ESP Code:

/*
* Name: Solar Tracker EspCode.ino (test version)
* Author: Sorin Liviu Jurj
*
* Description:
* This software will implement different testing testing techniques to test
* the software functionality and features. We will tackle each part of the
* code individually and attempt to show all the possible break points and
* try to detect possible fault errors using white box testing techniques.
* This testing is based on the AUnit arduino library which is a port of
* ArduinoUnit and Google Test testing platforms.
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#include <ctype.h>

// Library for testing
#include <AUnit.h>
using aunit::TestRunner; // name space for aunit to prevent name clashing

//WiFi Variables
const char* ssid = „Home Network“;
const char* password = „YOUR WIFI PASSWORD HERE“;
WiFiClient espClient;

// MQTT Variables
String chipID = “ „;

/*
* must be current system iP address
*/
const char* mqtt_server = „159.69.5.173“;

PubSubClient client(espClient);
char InTopic[16] = „in“;
char OutTopic[16] = „Out“;
char chipID_c[16] = „in“;

// Booleans
bool _Start = false;

volatile int ltsensor = 0;
volatile int rtsensor = 0;
volatile int rdsensor = 0;
volatile int ldsensor = 0;

String gh = „“;

// 14 and 12 are pin D5, and D6 ON THE NODEMCI ESP12
SoftwareSerial mySerial(14, 12, false, 256);

//———————————————
//———————————————
// TESTS
//———————————————
//———————————————
/*
* This test is configured to run only once and
* ensures that our ssid string contains only valid characters.
*/
test(ssidTest)
{
for(uint8_t i=0; i<sizeof(ssid); i++)
{
assertMoreOrEqual(ssid[i], ‚ ‚);
}
}

/*
* This test is configured to run only once and
* ensures that our password string contains only valid characters.
*/
test(passwordTest)
{
for(uint8_t i=0; i<sizeof(password); i++)
{
assertMoreOrEqual(password[i], ‚ ‚);
}
}

/*
* This test is configured to run only once and
* ensures that our mqtt address string is in the right format,
*/
test(mqttAddrTest)
{
for(uint8_t i=0; i<sizeof(mqtt_server); i++)
{
assertMoreOrEqual(mqtt_server[i], ‚.‘);
assertLessOrEqual(mqtt_server[i], ‚9‘);
}
}

/*
* This test a test to check the inTopic array
* which is dynamically generated using strings
* which are notorious for memory problems. In our
* test we check that all the characters are valid
* characters and also that the length of the array is
* less than 10
*/
test(InTopicTest)
{
uint8_t b = sizeof(InTopic);
assertLess(b, 10); // assert that the size of the array is less than 10

for(uint8_t i=0; i<sizeof(InTopic); i++)
{
assertMoreOrEqual(InTopic[i], ‚ ‚);
}
}

/*
* This test checks if the value of the sensor data received is in the
* reasonable range. If this value is outside the range 0 – 1024, we can
* concluse that the data was corrupted during transmission or a memmory
* problem has occured.
* This is a continous test and will be run over and over again.
*/
testing(sensorDataTest)
{
assertEqual(isDigit(ltsensor), 1); // makes sure that its a digit and not NAN
assertEqual(isDigit(rtsensor), 1);
assertEqual(isDigit(rdsensor), 1);
assertEqual(isDigit(ldsensor), 1);

assertMoreOrEqual(ltsensor, 0); // makes sure it is an unsigned integer, i.e greater than zero
assertMoreOrEqual(rtsensor, 0);
assertMoreOrEqual(rdsensor, 0);
assertMoreOrEqual(ldsensor, 0);

assertLessOrEqual(ltsensor, 1023); // makes sure that it is less than 1023
assertLessOrEqual(rtsensor, 1023);
assertLessOrEqual(rdsensor, 1023);
assertLessOrEqual(ldsensor, 1023);
}

/*
* We also have a test which tests the analog data received from the microcontroller
* to make sure that it is within the specified range.
*/
testing(incominingData)
{
uint8_t a = gh.length()-1;
assertLessOrEqual(a, 13);
}

/*
* Main Setup
*/
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);

/*
* The while statement is used to ensure that the serial communication is completely
* started before continuing with the program. This will prevent framing or data
* corruption errors if we try to send or receive data when the serial comm is not
* completely set up.
*/
while(!Serial && !mySerial);

/*
* It is advisable to disable the watchdog timer, on the ESP. The main duty of the watch dog timer
* it to reset the device if an error is detected (for example: if the device gets stuck in an
* infinite loop and no instructions are being processed). It is very important in embedded software
* development as it manages unpredicatable devices for us by reseting the system, which gives the system
* a chance to fix the error.
*/
ESP.wdtDisable();

delay(1000);

// Wifi connetion
Wifi_Connect();
delay(500);

MQTT_Connect();
}

///////////////////////////////////////////////
///////// MAIN LOOP ////////
/////////////////////////////////////////////
long lastTime1 = 0;
void loop()
{
/*
* We have to feed the Watch Dog timer regularly so that it does not timeout or
* think that it has encountered an error. This is a precautionary measure as the
* watchdog timer normally feeds itself when instruction are being processed.
* But it is a good practice to feed the watchdog timer at regular intervals just to
* account for unseen errors or delays in our code.
*/
ESP.wdtFeed();
Receive_Data(); // receive data

/*
* Sometimes connection to the MQTT Server can break for many reasons. conditional
* statement will attempt to reconnect to the server if the connectin is broker.
* But if the reconnection fails, we then restart the system.
*/
if (!client.connected())
{
MQTT_Connect();

// we add a 1 second delay to the reconnect loop so that we do not bang the server
// with too many requests.
delay(1000);
}

if(millis()-lastTime1 > 3000)
{
//client.publish(OutTopic, „Idle“);
lastTime1 = millis();
}

delay(100);
client.loop();

// this command runs all the defined tests.
TestRunner::run(); // run test from test queue

}

///////////////////////////////////////////////
///// MQTT AND WIFI FUNCTIONS //////
/////////////////////////////////////////////
void Wifi_Connect()
{
/*
* Before we try to connect we have to run a test which makes sure that the ssid
* and password for the wifi connection contain only valid characters.
*/
Serial.println();
Serial.print(„Connecting to „);
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(„.“);
ESP.wdtFeed();
}

// Generate ID
chipID = (String)ESP.getChipId();
chipID.toCharArray(chipID_c, chipID.length()+1);
Serial.print(„Device ID“); Serial.println(chipID_c);

// Generate Output Topic
String s_out = „From-„;
s_out += chipID;
s_out.toCharArray(OutTopic, s_out.length()+1);

// Generate Input Topic
String s_in = „To-„;
s_in += chipID;
s_in.toCharArray(InTopic, s_in.length()+1);

Serial.println(„“);
Serial.println(„WiFi connected“);
Serial.println(„IP address: „);
Serial.println(WiFi.localIP());

Serial.print(„Output Topic: „); Serial.println(OutTopic);
Serial.print(„Input Topic: „); Serial.println(InTopic);
}

void MQTT_Connect()
{
client.setServer(mqtt_server, 1883);
client.setCallback(MQTT_Receive_Callback);

Serial.print(„In Topic: „); Serial.println(InTopic);
Serial.print(„Out Topic: „); Serial.println(OutTopic);

delay(100);

int retry_counter = 0;

while (retry_counter < 20) // try to connect to web server 20 times
{
ESP.wdtFeed();
Serial.print(„Attempting MQTT connection to Web Server“);

if (client.connect(chipID_c))
{
Serial.println(„Connected to Web MQTT Server“);
//client.publish(OutTopic, „ESP connected“);
client.subscribe(InTopic);
Serial.print(„Successfully suscribed to topic „);
Serial.println(InTopic);
return ;
}
else {
Serial.print(„failed, rc=“);
Serial.println(client.state());
delay(1000);
}
retry_counter++;
}

// Restart device if connections fail
ESP.restart();
}

void MQTT_Receive_Callback(char* topic, byte* payload, unsigned int length)
{
Serial.print(„Message arrived [„);
Serial.print(topic);
Serial.print(„] „); Serial.println(„“);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();

ltsensor = getValue((char *)payload, ‚.‘, 1).toInt();
rtsensor = getValue((char *)payload, ‚.‘, 2).toInt();
ldsensor = getValue((char *)payload, ‚.‘, 3).toInt();
rdsensor = getValue((char *)payload, ‚.‘, 4).toInt();

UNO_Send();

// send acknowledgement message back to server
//client.publish(OutTopic, „Command received“);
}

void UNO_Send()
{
ESP.wdtFeed();
Serial.println(„sending to uno“);
mySerial.print(ltsensor);
mySerial.print(‚.‘);
mySerial.print(rtsensor);
mySerial.print(‚.‘);
mySerial.print(ldsensor);
mySerial.print(‚.‘);
mySerial.print(rdsensor);
mySerial.print(‚.‘);

mySerial.print(‚\r‘);
}

/*
* Function that receives data from the arduino uno.
* We have to run tests to confirm the integrity of the received data.
*/
void Receive_Data()
{
if(mySerial.available())
{
gh = „“;
gh = mySerial.readStringUntil(‚\r‘);
char *outdata = “ „;
gh.toCharArray(outdata, gh.length()-1);

Serial.println(„Publishing data to mqtt“);
Serial.println(gh);
client.publish(OutTopic, outdata);
return ;
}
}

String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() – 1;

for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : „“;
}

Nachfolgend möchte ich Ihnen auch eine Dokumentation und detaillierte Antworten auf Ihre möglichen Fragen zu unserem White-Box-Testverfahren für einen Solartracker vorstellen (Text auf English):

Section .I. INTRODUCTION – Questions and Answers
Q1. How can you justify that your White-box testing method implementation represents a novel approach in the renewable energy domain?
A1. In regards to modern White-box testing approaches, many state-of-the-art works present software-testing solutions exclusively for algorithms or software programs, which run on an operating system. In our situation, we are using a White-box testing method to generate test cases for a standalone software that was developed on an Arduino UNO board and we are checking the movements of our solar tracking device, which are directly translated from the testing code in real-time.
Q2. Is your White-box checking solution a regular testing method or a built-in-self-test approach?
A2. Our White-box testing solution uses two devices, one that generate test cases for our implementation, namely an ESP-8266 Wi-Fi module and an Arduino328 Microcontroller to which the injected values are directed. The Arduino UNO signifies the Device under Test (DUT) while the ESP-8266 comes an intermediate board between the Cloud Server Communication and the DUT. We could have reduced the costs of our testing system significantly if we resorted on an Arduino UNO Wi-Fi, which communicates, directly to the Cloud Interface. At the same time, we could have obtained a Built-In-Self-Test routine.
Q3. Why did you opt for a Message Queuing Telemetry Transport (MQTT) as a connectivity protocol for your Cloud Sever configuration?
A3. We chose the MQTT broker setup as our primary connectivity protocol because we wanted to integrate elements from the Internet-of-Things domain and with the idea in mind to implement a low-cost and lightweight publish/subscribe messaging transport. With just a small code footprint required, the MQTT protocol is ideal for home automations, sensor communications and healthcare providers. Nevertheless, it is compatible with mobile applications due to its small size, low power usage, minimized data packages and efficient distribution of information to one or more receivers.
Q4. You mentioned in the third paragraph of your paper that you are covering multiple aspects of the implementation. What do you mean more clearly with injecting virtual random integer values to the Device under test?
A4. While our main objective is to capture possible memory and buffer overflow errors, we are also focusing on the input-output variable flow testing. In other words, the virtual injected random values are transposing real-life measured voltage values in an unsigned range of values (as can be seen in the diagram below). The first range of values covers voltage inputs from 0 to 1.7 V received from the Optocoupler to the Arduino board which are properly scaled to a range of integer unsigned numbers from 0 to 1024. Why unsigned? … The short answer is that the input voltage measurements should be always positive values to prevent calculation errors of the algorithm. Negative induced voltages have the potential to alter the automation process of the solar system.
Q5. What exactly do you want to test by injecting random integer numbers into the system?
A5. With the previously described injection method, we are trying to generate test cases. We are already aware of the fact that in White-box testing a test case is composed of a random input value and the expected output. For our test cases, we insert unsigned integer values, which simulate voltages from the four corners of the PV panel, more precisely from each group of 3 solar cells. When those voltage values are collected from the four groups, they are further directed to the output of the Optocoupler. Before entering the analog inputs of the Arduino microcontroller, the values are calibrated with variable resistances mounted in the output circuit of the LTV847 module. Apart from this procedure, in our testing cases we are isolating the Arduino board from the Optocoupler and inject values through the ESP8266 Wi fi module. The result is the same … the only difference remaining in the fact that we calibrate the values inside the testing code and not in a technical manner. The output values are given by the movements of the solar panel in different directions, thus these movements can be translated into digital step signals.
Q6. Secondly, you said that you gain access to the Stepper motors to control them directly. How is that achievable?
A6. In order to gain direct control of the Stepper motors we had to integrate a recently appeared testing library called AUnit. Considered the follower of Arduino Unit 2.2, the AUnit is a unit-testing framework inspired by ArduinoUnit and Google Test. In contrast, AUnit consumes 65 % less flash memory than ArduinoUnit 2.2 on the AVR platform. AUnit has been successfully tested on AVR, Teensy-ARM and ESP8266. This testing library incorporates numerous functions, from which one of them allows the declaration of motor speed and all digital inputs of the Steppers (uint8_t). This proves to be helpful in situations when we want to receive feedback values from the stepper motors. Why we do that?… Well, these readings can be translated into a coordinates system, which tells us information about the current position of the solar panel. A further analysis of these registered values would map the exact movements and locations of the solar panel during one-day cycle.Q7. Thirdly, you mentioned that you could use the collected data to evaluate the probability of error positioning of the solar panel. Did you manage to test that?
A7. In terms of testing the acquired data, we did not manage to estimate the error positioning of the solar panel as the input integer values are randomly injected in the system opposed to the solar tracker that follows the movement of the Sun after a certain pattern. Under these conditions, we have to switch to manual injection of values to be able to register each set of feedback values when the solar panel remains fixed at the position. As the Sun moves from the East to the West side, the solar tracker updates its position periodically. If we store the data associated to each updated position we can train a neural network to predict weather forecast. However, this aspect will remain as future research direction.
Q8. The most important aspect of your work is the detection of memory errors and buffer overflows. Can you explain what type of memory errors you are targeting in your paper and how exactly buffer overflows manifest in your situation?
A8. Buffer overflows, like in most software programs, appear when adjacent memory locations are supplementary written by the software code (caused by spontaneous bugs) or as a result of a cybernetic attack. For our Wireless based Software Testing approach both of the mentioned causes represent valid reasons. For instance, our Cloud based testing interface allows sending of four data packages, each of them being separated by a dot (see figure below).In the figure from the previous page, the MQTT broker will send four data packages consisting of 4 bytes of information, usually storing integer ciphers from 0 to 9. For the Left Top Sensor we inject for example the value 1005, which is a valid number as it fits the range (0– 1024). In Binary-Coded Decimal (BCD) system each data byte is encrypted using 8 bits of information. For digit 1 we have 00000001, for 0 it is 00000000 and for 5 – 00000101. For the entire number 1005 we have the following binary code 00000001000000000000000000000101, which means that each data package is limited to a number of 32 bits. Let us consider that we receive data packages in the previous format. As can be observed, the first three data packages are affected by buffer overruns. In other words, an additional byte of information is written in a memory location that is not even supposed to be there. Large data packages, which exceed 10.000 are able to generate the memory errors that we target in our work: control flow, calculation, error handling and communication errors.Q9. It is said, “Prevention is better than Cure”. Did you find any methods to intercept the possible errors that you encountered during test phases?
A9. In order to avoid buffer overflow scenarios we managed to minimize the use of buffers and arrays and instead resorted on a personal method based on individual objects to considerably reduce memory fragmentation. We also reduced the number of strings, which are notorious for bad memory management.
Section .II. RELATED WORK – Questions and Answers
Q10. How exactly does your contribution distinguish itself from other state-of-the-art works in the domain?
A10. As far as we documented ourselves, current papers in the domain study either White-box testing solutions for software applications or parameter testing for fixed solar panels. We were not able to find a crossover between white-box testing and solar tracking devices verification using this type of software strategy.
Section .III. SYSTEM OVERVIEW – Questions and Answers
Q11. Besides the ESP8266 Wi-Fi module, Arduino UNO board, MQTT protocol and Stepper motors what other facilities did you use to accomplish the White-box testing method?
A11. For our White-box testing project, we considered to build a Web Interface based on the Node-Red application to facilitate the placement and defining of individual functions for transmitting data through the MQTT protocol. The Node-RED platform is also tailored towards the IoT and embedded systems domain.
Q12. Why did you choose to implement a Mobile app?
A12. In the initial implementation stage, we only wanted to realize a local wireless testing solution based on the White-box testing method. However, the system was heavily dependent on the local server configuration, which was installed on a laptop placed nearby a wireless router. Because many applications nowadays run over a Cloud server to make data transfer more convenient from different locations, we decided to construct a Mobile application based on the Ionic Framework. Our app is a wrapper around the Node-RED and acts as a browser, providing us access to the Node-RED Dashboard. We developed our mobile application in two versions: an iOS app as well as an Android app.
Section .IV. WIRELESS-BASED SOFTWARE TESTING – Questions and Answers
Q13. How would you describe in your own words a Wireless-Based Software Testing (WBST)?
A13. We called our White-box testing strategy a WBST mainly because it is not a built-in-self test. In other words, we did not decide to implement a testing algorithm that runs on the same DUT concomitant with the solar tracking automation algorithm. We wanted to separate the Main microcontroller from the secondary microcontroller to highlight the interaction between the hardware, software and cloud layer. The result was a logical diagram, which described the flow of data and control in a straightforward manner.
Q14. You addressed the problem of the Node-red interface in section IV, while the figure is depicted in the previous section of the paper. What is the role of the implemented nodes?
A14. First of all, the nodes created in the Node-Red interface are a graphical representation of the programs main functions so that the casual reader gets a clear picture of how the injection process works. The first set of nodes from the left hand side are the inputs of the algorithm, which illustrate the four groups of three solar cells from each corner of the panel. Let us not forget the fact that we are actually creating a simulation environment for our solar tracking device. With the help of the gather function each input value (that can be generated automatically or manually by the user) is injected in a string of values separated by a dot which enters the Arduino board. From here the main algorithm will process the unsigned integer values and will provide an output digital signal that will move the solar tracker in one direction or vice-versa. The defined values “To-7344478” and “From-7344478” are the In-topic and Out-topic of the ESP8266 secondary microcontroller. In both cases the value represents a unique identification number which is essential when publishing or receiving information.
Q15. Can you describe in a few lines how the White-box Testing Strategy Execution Flow works according to the diagram?
A15. Well, according to the constructed diagram, our White-box testing routine will start of by initializing the testing environment. This is done by turning on the ESP8266 Wi Fi module and attempting to connect to the Internet. At this point, a set of four tests, which are executed only once, are started by the test program to verify SSID, Password, MQTT Address and InTopic. Once these entities are verified by the test program the algorithm will continue to run the regular solar tracking automation process and will continuously test sensor data and incoming data from the ESP module. We are mainly focusing on integer number length testing, communication testing, In-topic and Out-topic testing, stepper motor speed testing and control flow testing.

Section .V. EXPERIMENTAL RESULTS – Questions and Answers
Q16. You divided this section in two major parts: solar tracker basic movement testing and coverage testing. How did you quantify the results in the first scenario?
A16. In regards to the first testing scenario, we wanted to inject manually integer values to verify if the solar tracker directs the payload according to the initial developed algorithm. The majority of state-of-the-art solar trackers orient the panel where the maximum energy from the Sun is concentrated. This is usually achieved by mounting light sensing sensors such as LDR’s in the four corners of the solar panel. We removed the need to install LDR’s and opted instead to employ a method for tracking the shadow. Let us further explain this approach. For example, if we mount four solar barriers in the corners of the panel and while the sun is moving from the East to the West side it will produce a shaded area where the screens are placed. Now, in real-life scenarios, most of the time only a pair of corners are shaded during the day depending on where the Sun is positioned on the sky. For our test cases, we first injected a higher value in one of the corners of the panel, as it is depicted on the next page:
RT – 903
LT – 783
BR – 790
BL – 800
While the first integer value is associated with 1.5 V in real-life (see scaling axes in Q4), the next three values represent a value close to 1.3 V. According to the algorithm, the program will calculate the average of top-bottom and left side – right side voltages (in our case integer numbers):
Average Top = (RT + LT) / 2 = 843
Average Bottom = (BR + BL) / 2 = 795
It is more than obvious that the average of the top-bottom sides exceeds the next average value, so in other words the shadow was detected on the bottom part of the panel:Now, the pseudocode will continue with the approximation of the two other averages:
Average Left = (LT + BL) / 2 = 792
Average Right = (RT + BR) / 2 = 847

As can be seen the average sensor value on the right is significantly greater than the average on the left which results in a left rotation of the solar panel.
The second experiment involved injecting two high integer values in a pair of corners of the solar panel. We can exclude the cases with Left Top – Bottom Right Sensor and Right Top – Bottom Left Sensor because these groups connect two corners of the solar panel in a diagonal manner, which in real life doesn’t occur (we can’t have a shadow describing this shape). In other words, let us take the following example:
RT – 790
LT – 800
BR – 903
BL – 900
We changed the value from the previous test case (Left Top Sensor) to 900. Now let us follow the same steps as before:
Average Top = (RT + LT) / 2 = 795
Average Bottom = (BR + BL) / 2 = 902
Because this time we obtained a higher average value on the bottom side of the panel, the solar tracker will rotate the panel up to eliminate the casted shadow. At the next step, the algorithm will calculate the following values:
Average Left = (LT + BL) / 2 = 850
Average Right = (RT + BR) / 2 = 847
In this scenario, the gap between the average values is very small so the solar tracker will eventually not rotate the panel to the left side.
As a conclusion, depending on the injected values, the solar tracker will rotate the panel in two directions in a parallel manner. The next two test cases do not bring any new elements to the table. We have to understand that usually a left-right or up-down movement is defined from the overlapping of the gathered digital output signals. Overlapping means comparing each two signals and finding a relevant delay between the step signals to justify the corresponding rotation. Q17. In the last stages of the experiments, you described the coverage obtained by the White-box testing strategy. How did you quantify the results?
A17. The challenging part of our task was to interpret the results of the White-box testing approach. We divided each fault – error type in categories based on the value range in which those were detected. After gathering sufficient test probes, we continued with calculating the coverage (in percentage) for each of the target errors: control flow, communication, calculation and error handling errors. An average coverage of 70 % was achieved by the testing algorithm, which shows that our first attempt in constructing an adaptation of the White-box testing was a success. We will probably extend the testing facilities of the current work with hardware testing features resorting on the IEEE 1149.1 Standard.
Q18. What is ultimately the main benefit of the White-Box Testing Strategy?
A18. Our White-Box testing approach significantly reduces the test time which would normally run over several days. By isolating the Arduino UNO from the Solar Tracker feedback sensors (4 corners with the groups of 3 PV cells each), we inject unassigned integer values in order to simulate real-life voltages.

Leave a Comment

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

Scroll Up