Related
so I am having a weird issue, I am using the C/C++ SDK with visual studio to program a raspberry pi pico. The project is using a rotary encoder with push button and lcd to control a seperate PCB. Almost everything is working but when I try and send an SPI command on SPI1 the program just completely stops working, as in using the encoder or button causes no change in either serial monitor or in the lcd.
I know it is an issue with the spi1 because if I change it to spi0 I get no crash and I also tried changing the value I was sending on spi1 and that made no difference and it still crashed.
Below is a part of the code that shows how I used spi0 which works and spi1 which doesnt work, I can include the full project if needed but it is kinda long so, let me know if it is needed.
if(Mode_Counter == 1) { // data to send on SPI for Mode 1
Ctrl_bit_and_data = data.Ctrl_bit_and_Data_Func_Write();
spi_write16_blocking(SPI_PORT, &Ctrl_bit_and_data, 1); // this is spi0 and works fine
}
if(Mode_Counter == 3) {
Counter_LV = Counter;
Count_LV.set_position_LV(Counter_LV);
Ctrl_bit_and_data_LV = data_LV.Ctrl_bit_and_Data_Func_Write_LV();
spi_write16_blocking(spi1, &Ctrl_bit_and_data_LV, 1); // this is the line that isnt working
}
Any help or guidance with this would be greatly appreciated I am very stuck as to the issue with this.
I was trying the code with SYCL/DPC++. I have two GPUs present on my device. How can I specify that my code needs to run on a particular GPU device?
When I am trying to run my code using "gpu-selector" only one default one is used to run. How can I use the other GPU device in order to run my code?
Here is my code.
#include <iostream>
#include <CL/sycl.hpp>
using namespace sycl;
using namespace std;
int main() {
queue my_gpu( gpu_selector{} );
cout << "My GPU Device: " <<
my_gpu.get_device().get_info<info::device::name>() << "\n";
return 0;
}
Can someone help me out with how can I run my code on a particular GPU device?
Thanks in Advance!
Yes, it is possible to select a particular GPU device. Please find the below code to get the results from a specific GPU device.
class my_selector : public device_selector {
public:
int operator()(const device &dev) const override {
if (
dev.get_info<info::device::name>().find("gpu_vendor_name")
!= std::string::npos &&
dev.get_info<info::device::vendor>().find("gpu_device_name")
!= std::string::npos)
return 1;
}
return -1;
}
};
In this code, we can specify the name of the GPU vendor in ("gpu_vendor_name") as per your requirement. If we have two GPU devices with the same vendor then we can also specify the one we want to run code in the GPU device("gpu_device_name").
The highest return value will be selected to run the code on the GPU device which we want.
The answer by Varsha is a good general solution.
But since your question is tagged with DPC++, I think it is worth mentioning an alternative approach:
You can set SYCL_DEVICE_FILTER environment variable to control device detection results. E.g., SYCL_DEVICE_FILTER=opencl:gpu:1 will make it so only the second GPU in the OpenCL backend is visible by the application. It will even hide the Host device.
That is DPC++-specific, and will not work with other implementations. But, for example, with hipSYCL you can use CUDA_VISIBLE_DEVICES or HIP_VISIBLE_DEVICES to achieve similar results.
So I created a code in C++ using visual studio and I was learning about making classes and using methods/functions. The program was working fine until I wrote the using namespace std; and suddenly trying to run my code I got a LNK1168 error and I tried everything to fix it.
I made sure that no tasks were running, and I saved it and closed it and opened it back up to run it again and still no matter what I did, the LNK1168 error pops back up.
I then switched from debugging x86 to debugging x64 and my code works normally with the x64.
Does this matter? If so why, if not then what should I do?
#include<iostream>
// did not include the using namespace std; because that's when my issue started
// not sure if it had something to do with it
class Player
{
public:
int x, y;
int speed;
void movin(int xa, int ya)
{
x += xa * speed;
y += ya * speed;
}
};
int main()
{
Player player;
player.movin(1, 1);
std::cout << "apples are tasty"; // this is to make sure my code prints something
std::cin.get();
return 0;
}
I tried looking up youtube videos but nothing helps! Oddly enough the x64 works but not the usual x86? Does this affect my code or how I compile my code? Would it make things run slower? I am confused.
I tried looking at the Windows Help site after clicking the error and nothing helps. Does anyone know?
LNK1168 Means your executable is still running when you try to compile the code. Close the app, and then compile.
I'd like to be able to unit test my Arduino code. Ideally, I would be able to run any tests without having to upload the code to the Arduino. What tools or libraries can help me with this?
There is an Arduino emulator in development which could be useful, but it doesn't yet seem to be ready for use.
AVR Studio from Atmel contains a chip simulator which could be useful, but I can't see how I would use it in conjunction with the Arduino IDE.
Don't Run Unit Tests on the Arduino Device or Emulator
The case against microcontroller Device/Emulator/Sim-based tests
There's a lot of discussion about what unit test means and I'm not
really trying to make an argument about that here. This post is not
telling you to avoid all practical testing on your ultimate target
hardware. I am trying to make a point about optimizing your
development feedback cycle by eliminating your target hardware from
your most mundane and frequent tests. The units under test are assumed
to be much smaller than the whole project.
The purpose of unit testing is to test the quality of your own code. Unit tests should generally never test the functionality of factors outside of your control.
Think about it this way: Even if you were to test functionality of the Arduino library, the microcontroller hardware, or an emulator, it is absolutely impossible for such test results to tell you anything about the quality of your own work. Hence, it is far more valuable and efficient to write unit tests that do not run on the target device (or emulator).
Frequent testing on your target hardware has a painfully slow cycle:
Tweak your code
Compile and upload to Arduino device
Observe behavior and guess whether your code is doing what you expect
Repeat
Step 3 is particularly nasty if you expect to get diagnostic messages via serial port but your project itself needs to use your Arduino's only hardware serial port. If you were thinking that the SoftwareSerial library might help, you should know that doing so is likely to disrupt any functionality that requires accurate timing like generating other signals at the same time. This problem has happened to me.
Again, if you were to test your sketch using an emulator and your time-critical routines ran perfectly until you uploaded to the actual Arduino, then the only lesson you're going to learn is that the emulator is flawed--and knowing this still reveals nothing about the quality of your own work.
If it's silly to test on the device or emulator, what should I do?
You're probably using a computer to work on your Arduino project. That computer is orders of magnitudes faster than the microcontroller. Write the tests to build and run on your computer.
Remember, the behavior of the Arduino library and microcontroller should be assumed to be either correct or at least consistently incorrect.
When your tests produce output contrary to your expectations, then you likely have a flaw in your code that was tested. If your test output matches your expectations, but the program does not behave correctly when you upload it to the Arduino, then you know that your tests were based on incorrect assumptions and you likely have a flawed test. In either case, you will have been given real insights on what your next code changes should be. The quality of your feedback is improved from "something is broken" to "this specific code is broken".
How to Build and Run Tests on Your PC
The first thing you need to do is identify your testing goals. Think about what parts of your own code you want to test and then make sure to construct your program in such a way that you can isolate discrete parts for testing.
If the parts that you want to test call any Arduino functions, you will need to provide mock-up replacements in your test program. This is much less work than it seems. Your mock-ups don't have to actually do anything but providing predictable input and output for your tests.
Any of your own code that you intend to test needs to exist in source files other than the .pde sketch. Don't worry, your sketch will still compile even with some source code outside of the sketch. When you really get down to it, little more than your program's normal entry point should be defined in the sketch file.
All that remains is to write the actual tests and then compile it using your favorite C++ compiler! This is probably best illustrated with a real world example.
An actual working example
One of my pet projects found here has some simple tests that run on the PC. For this answer submission, I'll just go over how I mocked-up some of Arduino library functions and the tests I wrote to test those mock-ups. This is not contrary to what I said before about not testing other people's code because I was the one who wrote the mock-ups. I wanted to be very certain that my mock-ups were correct.
Source of mock_arduino.cpp, which contains code that duplicates some support functionality provided by the Arduino library:
#include <sys/timeb.h>
#include "mock_arduino.h"
timeb t_start;
unsigned long millis() {
timeb t_now;
ftime(&t_now);
return (t_now.time - t_start.time) * 1000 + (t_now.millitm - t_start.millitm);
}
void delay( unsigned long ms ) {
unsigned long start = millis();
while(millis() - start < ms){}
}
void initialize_mock_arduino() {
ftime(&t_start);
}
I use the following mock-up to produce readable output when my code writes binary data to the hardware serial device.
fake_serial.h
#include <iostream>
class FakeSerial {
public:
void begin(unsigned long);
void end();
size_t write(const unsigned char*, size_t);
};
extern FakeSerial Serial;
fake_serial.cpp
#include <cstring>
#include <iostream>
#include <iomanip>
#include "fake_serial.h"
void FakeSerial::begin(unsigned long speed) {
return;
}
void FakeSerial::end() {
return;
}
size_t FakeSerial::write( const unsigned char buf[], size_t size ) {
using namespace std;
ios_base::fmtflags oldFlags = cout.flags();
streamsize oldPrec = cout.precision();
char oldFill = cout.fill();
cout << "Serial::write: ";
cout << internal << setfill('0');
for( unsigned int i = 0; i < size; i++ ){
cout << setw(2) << hex << (unsigned int)buf[i] << " ";
}
cout << endl;
cout.flags(oldFlags);
cout.precision(oldPrec);
cout.fill(oldFill);
return size;
}
FakeSerial Serial;
and finally, the actual test program:
#include "mock_arduino.h"
using namespace std;
void millis_test() {
unsigned long start = millis();
cout << "millis() test start: " << start << endl;
while( millis() - start < 10000 ) {
cout << millis() << endl;
sleep(1);
}
unsigned long end = millis();
cout << "End of test - duration: " << end - start << "ms" << endl;
}
void delay_test() {
unsigned long start = millis();
cout << "delay() test start: " << start << endl;
while( millis() - start < 10000 ) {
cout << millis() << endl;
delay(250);
}
unsigned long end = millis();
cout << "End of test - duration: " << end - start << "ms" << endl;
}
void run_tests() {
millis_test();
delay_test();
}
int main(int argc, char **argv){
initialize_mock_arduino();
run_tests();
}
This post is long enough, so please refer to my project on GitHub to see some more test cases in action. I keep my works-in-progress in branches other than master, so check those branches for extra tests, too.
I chose to write my own lightweight test routines, but more robust unit-test frameworks like CppUnit are also available.
In the absence of any pre-existing unit test frameworks for Arduino, I have created ArduinoUnit. Here's a simple Arduino sketch demonstrating its use:
#include <ArduinoUnit.h>
// Create test suite
TestSuite suite;
void setup() {
Serial.begin(9600);
}
// Create a test called 'addition' in the test suite
test(addition) {
assertEquals(3, 1 + 2);
}
void loop() {
// Run test suite, printing results to the serial port
suite.run();
}
I have considerable success unit testing my PIC code by abstracting out the hardware access and mocking it in my tests.
For example, I abstract PORTA with
#define SetPortA(v) {PORTA = v;}
Then SetPortA can easily be mocked, without adding overhead code in the PIC version.
Once the hardware abstraction has been tested a while I soon find that generally code goes from the test rig to the PIC and works first time.
Update:
I use a #include seam for the unit code, #including the unit code in a C++ file for the test rig, and a C file for the target code.
As an example I want to multiplex four 7 segment displays, one port driving the segments and a second selecting the display. The display code interfaces with the displays via SetSegmentData(char) and SetDisplay(char). I can mock these in my C++ test rig and check that I get the data I expect. For the target I use #define so that I get a direct assignment without the overhead of a function call
#define SetSegmentData(x) {PORTA = x;}
It seems that emulino would do the job perfectly.
Emulino is an emulator for the Arduino platform by Greg Hewgill. (Source)
GitHub repository
simavr is an AVR simulator using avr-gcc.
It already supports a few ATTiny and ATMega microcontrollers, and - according to the author - it's easy to add some more.
In the examples lies simduino, an Arduino emulator. It supports running the Arduino bootloader and can be programmed with avrdude through Socat (a modified Netcat).
You can unit test in Python with my project, PySimAVR. Arscons is used for building and simavr for simulation.
Example:
from pysimavr.sim import ArduinoSim
def test_atmega88():
mcu = 'atmega88'
snippet = 'Serial.print("hello");'
output = ArduinoSim(snippet=snippet, mcu=mcu, timespan=0.01).get_serial()
assert output == 'hello'
Start test:
$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok
I built arduino_ci for this purpose. Although it's limited to testing Arduino libraries (and not standalone sketches), it enables unit tests to be run either locally or on a CI system (like Travis CI or Appveyor).
Consider a very simple library in your Arduino Library directory, called DoSomething, with do-something.cpp:
#include <Arduino.h>
#include "do-something.h"
int doSomething(void) {
return 4;
};
You'd unit test it as follows (with a test file called test/is_four.cpp or some such):
#include <ArduinoUnitTests.h>
#include "../do-something.h"
unittest(library_does_something)
{
assertEqual(4, doSomething());
}
unittest_main() // this is a macro for main(). just go with it.
That's all. If that assertEqual syntax and test structure looks familiar, it's because I adopted some of Matthew Murdoch's ArduinoUnit library
that he referred to in his answer.
See Reference.md for more information about unit testing I/O pins, the clock, Serial ports, etc.
These unit tests are compiled and run using a script contained in a ruby gem. For examples of how to set that up, see the README.md or just copy from one of these examples:
A practical example, testing a Queue implementation
Another set of tests on another Queue project
A complex example, simulating a library that controls an interactive device over a SoftwareSerial connection as part of the Adafruit FONA library
The DoSomething example library shown above, used to test arduino_ci itself
I am not aware of any platform which can test Arduino code.
However, there is the Fritzing platform, which you can use to model the hardware and later on export PCB diagrams and stuff.
Worth checking.
We are using Arduino boards for data acquisition in a large scientific experiment. Subsequently, we have to support several Arduino boards with different implementations. I wrote Python utilities to dynamically load Arduino hex images during unit testing. The code found on the link below supports Windows and Mac OS X via a configuration file. To find out where your hex images are placed by the Arduino IDE, hit the shift key before you hit the build (play) button. Hit the shift key while hitting upload to find out where your avrdude (command line upload utility) is located on your system / version of Arduino. Alternatively, you can look at the included configuration files and use your install location (currently on Arduino 0020).
http://github.com/toddstavish/Python-Arduino-Unit-Testing
This program allows automated running of several Arduino unit tests. The testing process is started on the PC but the tests run on the actual Arduino hardware. One set of unit tests is typically used to test one Arduino library.
(this
Arduino Forum: http://arduino.cc/forum/index.php?topic=140027.0
GitHub project page: http://jeroendoggen.github.com/Arduino-TestSuite
Page in the Python Package Index: http://pypi.python.org/pypi/arduino_testsuite
The unit tests are written with the "Arduino Unit Testing Library": http://code.google.com/p/arduinounit
The following steps are performed for each set of unit tests:
Read the config file to find out which tests to run
The script compiles and uploads an Arduino sketch that contains the unit testing code.
The unit tests are run on the Arduino board.
The results of the test are printed over the serial port and analyzed by the Python script.
The script starts the next test, repeating the above steps for all test that are requested in the configuration file.
The script prints a summary showing an overview of all the failed/passed tests in the complete testsuite.
Keep hardware-specific code separate or abstracted away from the rest so you can test and debug that bigger "rest" on any platform for which you have good tools and with which you're familiar most.
Basically, try to build as much of the final code from as many known-to-work building blocks as possible. The remaining hardware-specific work will then be much easier and faster. You may finish it by using existing emulators and/or emulating devices on your own. And then, of course, you'll need to test the real thing somehow. Depending on circumstances, that may or may not be very well automatable (i.e. who or what will press buttons and provide other inputs? who or what will observe and interpret various indicators and outputs?).
James W. Grenning writes great books and this one is about unit testing embedded C code Test Driven Development for Embedded C.
I am using Searduino when writing Arduino code. Searduino is an Arduino simulator and a development environment (Makefiles, C code ...) that makes it easy to hack in C/C++ using your favorite editor. You can import Arduino sketches and run them in the simulator.
Screenshot of Searduino 0.8: http://searduino.files.wordpress.com/2014/01/jearduino-0-8.png
Searduino 0.9 will be released and a video will be recorded as soon as the lasts tests are done .... in a day or two.
Testing on the simulator is not to be considered as real tests, but it certainly have helped me a lot in finding stupid/logical mistakes (forgetting to do pinMode(xx, OUTPUT), etc.).
BTW: I am one of the people developing Searduino.
There is a project called ncore, which provides native core for Arduino. And allows you to write tests for Arduino code.
From the project description
The native core allows you to compile and run Arduino sketches on the
PC, generally with no modification. It provides native versions of
standard Arduino functions, and a command-line interepreter to give
inputs to your sketch that would normally come from the hardware
itself.
Also on the "what do I need to use it" section
If you want to build the tests, you'll need cxxtest from
http://cxxtest.tigris.org. NCORE has been tested with cxxtest 3.10.1.
If you want to unit-test code outside MCU (on desktop), check out libcheck:
https://libcheck.github.io/check/
I used it to test my own embedded code few times. It's pretty robust framework.
You can use emulare — you can drag and drop a microcontroller on a diagram and run your code in Eclipse. The documentation on the website tells you how to set it up.
Use Proteus VSM with an Arduino library to debug your code or to test it.
It is a best practice before getting your code onboard, but be sure with timings because the simulation does not run realtime as they run on the board.
Try Autodesk circuit simulator. It allows to test Arduino code and circuits with many other hardware components.
In basic Arduino is written with C and C++, even libraries of arduino are written in C and C++. So,in simple terms just handle the code as C and C++ and try doing the unit testing. Here, by the word "handle" I mean you to change all the basic syntax like serial.println to sysout, pinmode to varaibles, void loop to while() loop which breaks either in keystock or after some iteration.
I know this is little a long process and not so straight forward.On my personal experience, once you get to do with it, this turns to be more reliable.
-Nandha_Frost
In case you are interested in running an INO sketch and checkout the serial output, I have a working implementation of that in my Arduino NMEA checksum project.
The following script takes the file and uses Arduino CLI to compile it to a HEX file which is then loaded to SimAVR which evaluates it and prints the serial output. Since all Arduino programs run forever without really having an option of killing themselves (exit(0) doesn't work), I let the sketch run for a few seconds and then diff the captured output with expected output.
Download and extract Arduino CLI (in this case version 0.5.0 - latest at the time of writing):
curl -L https://github.com/arduino/arduino-cli/releases/download/0.5.0/arduino-cli_0.5.0_Linux_64bit.tar.gz -o arduino-cli.tar.gz
tar -xvzf arduino-cli.tar.gz
Now you can update the index and install the appropriate core:
./arduino-cli core update-index
./arduino-cli core install arduino:avr
Assuming your sketch is named nmea-checksum.ino, to get ELF and HEX, run:
./arduino-cli compile -b arduino:avr:uno nmea-checksum.ino
Next up, SimAVR to run the HEX (or ELF) - I build from source because the latest release didn't work for me:
sudo apt-get update
sudo apt-get install -y build-essential libelf-dev avr-libc gcc-avr freeglut3-dev libncurses5-dev pkg-config
git clone https://github.com/buserror/simavr.git
cd simavr
make
Successful compilation will give you simavr/run_avr which you can use to run the sketch. Like I said, timeout it otherwise it will never terminate:
cd simavr
timeout 10 ./run_avr -m atmega168 -f 16000000 ../../nmea-checksum.ino.arduino.avr.uno.elf &> nmea-checksum.ino.clog || true
The generated file will have ANSI color code control characters wrapping the serial output, to get rid of those:
cat nmea-checksum.ino.clog | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > nmea-checksum.ino.log
cat nmea-checksum.ino.log
Now all you need to do is compared this file to a known good file:
diff nmea-checksum.ino.log ../../nmea-checksum.ino.test
If there are no differences, diff will exit with code 0, otherwise the script will fail.
I'd like to be able to unit test my Arduino code. Ideally, I would be able to run any tests without having to upload the code to the Arduino. What tools or libraries can help me with this?
There is an Arduino emulator in development which could be useful, but it doesn't yet seem to be ready for use.
AVR Studio from Atmel contains a chip simulator which could be useful, but I can't see how I would use it in conjunction with the Arduino IDE.
Don't Run Unit Tests on the Arduino Device or Emulator
The case against microcontroller Device/Emulator/Sim-based tests
There's a lot of discussion about what unit test means and I'm not
really trying to make an argument about that here. This post is not
telling you to avoid all practical testing on your ultimate target
hardware. I am trying to make a point about optimizing your
development feedback cycle by eliminating your target hardware from
your most mundane and frequent tests. The units under test are assumed
to be much smaller than the whole project.
The purpose of unit testing is to test the quality of your own code. Unit tests should generally never test the functionality of factors outside of your control.
Think about it this way: Even if you were to test functionality of the Arduino library, the microcontroller hardware, or an emulator, it is absolutely impossible for such test results to tell you anything about the quality of your own work. Hence, it is far more valuable and efficient to write unit tests that do not run on the target device (or emulator).
Frequent testing on your target hardware has a painfully slow cycle:
Tweak your code
Compile and upload to Arduino device
Observe behavior and guess whether your code is doing what you expect
Repeat
Step 3 is particularly nasty if you expect to get diagnostic messages via serial port but your project itself needs to use your Arduino's only hardware serial port. If you were thinking that the SoftwareSerial library might help, you should know that doing so is likely to disrupt any functionality that requires accurate timing like generating other signals at the same time. This problem has happened to me.
Again, if you were to test your sketch using an emulator and your time-critical routines ran perfectly until you uploaded to the actual Arduino, then the only lesson you're going to learn is that the emulator is flawed--and knowing this still reveals nothing about the quality of your own work.
If it's silly to test on the device or emulator, what should I do?
You're probably using a computer to work on your Arduino project. That computer is orders of magnitudes faster than the microcontroller. Write the tests to build and run on your computer.
Remember, the behavior of the Arduino library and microcontroller should be assumed to be either correct or at least consistently incorrect.
When your tests produce output contrary to your expectations, then you likely have a flaw in your code that was tested. If your test output matches your expectations, but the program does not behave correctly when you upload it to the Arduino, then you know that your tests were based on incorrect assumptions and you likely have a flawed test. In either case, you will have been given real insights on what your next code changes should be. The quality of your feedback is improved from "something is broken" to "this specific code is broken".
How to Build and Run Tests on Your PC
The first thing you need to do is identify your testing goals. Think about what parts of your own code you want to test and then make sure to construct your program in such a way that you can isolate discrete parts for testing.
If the parts that you want to test call any Arduino functions, you will need to provide mock-up replacements in your test program. This is much less work than it seems. Your mock-ups don't have to actually do anything but providing predictable input and output for your tests.
Any of your own code that you intend to test needs to exist in source files other than the .pde sketch. Don't worry, your sketch will still compile even with some source code outside of the sketch. When you really get down to it, little more than your program's normal entry point should be defined in the sketch file.
All that remains is to write the actual tests and then compile it using your favorite C++ compiler! This is probably best illustrated with a real world example.
An actual working example
One of my pet projects found here has some simple tests that run on the PC. For this answer submission, I'll just go over how I mocked-up some of Arduino library functions and the tests I wrote to test those mock-ups. This is not contrary to what I said before about not testing other people's code because I was the one who wrote the mock-ups. I wanted to be very certain that my mock-ups were correct.
Source of mock_arduino.cpp, which contains code that duplicates some support functionality provided by the Arduino library:
#include <sys/timeb.h>
#include "mock_arduino.h"
timeb t_start;
unsigned long millis() {
timeb t_now;
ftime(&t_now);
return (t_now.time - t_start.time) * 1000 + (t_now.millitm - t_start.millitm);
}
void delay( unsigned long ms ) {
unsigned long start = millis();
while(millis() - start < ms){}
}
void initialize_mock_arduino() {
ftime(&t_start);
}
I use the following mock-up to produce readable output when my code writes binary data to the hardware serial device.
fake_serial.h
#include <iostream>
class FakeSerial {
public:
void begin(unsigned long);
void end();
size_t write(const unsigned char*, size_t);
};
extern FakeSerial Serial;
fake_serial.cpp
#include <cstring>
#include <iostream>
#include <iomanip>
#include "fake_serial.h"
void FakeSerial::begin(unsigned long speed) {
return;
}
void FakeSerial::end() {
return;
}
size_t FakeSerial::write( const unsigned char buf[], size_t size ) {
using namespace std;
ios_base::fmtflags oldFlags = cout.flags();
streamsize oldPrec = cout.precision();
char oldFill = cout.fill();
cout << "Serial::write: ";
cout << internal << setfill('0');
for( unsigned int i = 0; i < size; i++ ){
cout << setw(2) << hex << (unsigned int)buf[i] << " ";
}
cout << endl;
cout.flags(oldFlags);
cout.precision(oldPrec);
cout.fill(oldFill);
return size;
}
FakeSerial Serial;
and finally, the actual test program:
#include "mock_arduino.h"
using namespace std;
void millis_test() {
unsigned long start = millis();
cout << "millis() test start: " << start << endl;
while( millis() - start < 10000 ) {
cout << millis() << endl;
sleep(1);
}
unsigned long end = millis();
cout << "End of test - duration: " << end - start << "ms" << endl;
}
void delay_test() {
unsigned long start = millis();
cout << "delay() test start: " << start << endl;
while( millis() - start < 10000 ) {
cout << millis() << endl;
delay(250);
}
unsigned long end = millis();
cout << "End of test - duration: " << end - start << "ms" << endl;
}
void run_tests() {
millis_test();
delay_test();
}
int main(int argc, char **argv){
initialize_mock_arduino();
run_tests();
}
This post is long enough, so please refer to my project on GitHub to see some more test cases in action. I keep my works-in-progress in branches other than master, so check those branches for extra tests, too.
I chose to write my own lightweight test routines, but more robust unit-test frameworks like CppUnit are also available.
In the absence of any pre-existing unit test frameworks for Arduino, I have created ArduinoUnit. Here's a simple Arduino sketch demonstrating its use:
#include <ArduinoUnit.h>
// Create test suite
TestSuite suite;
void setup() {
Serial.begin(9600);
}
// Create a test called 'addition' in the test suite
test(addition) {
assertEquals(3, 1 + 2);
}
void loop() {
// Run test suite, printing results to the serial port
suite.run();
}
I have considerable success unit testing my PIC code by abstracting out the hardware access and mocking it in my tests.
For example, I abstract PORTA with
#define SetPortA(v) {PORTA = v;}
Then SetPortA can easily be mocked, without adding overhead code in the PIC version.
Once the hardware abstraction has been tested a while I soon find that generally code goes from the test rig to the PIC and works first time.
Update:
I use a #include seam for the unit code, #including the unit code in a C++ file for the test rig, and a C file for the target code.
As an example I want to multiplex four 7 segment displays, one port driving the segments and a second selecting the display. The display code interfaces with the displays via SetSegmentData(char) and SetDisplay(char). I can mock these in my C++ test rig and check that I get the data I expect. For the target I use #define so that I get a direct assignment without the overhead of a function call
#define SetSegmentData(x) {PORTA = x;}
It seems that emulino would do the job perfectly.
Emulino is an emulator for the Arduino platform by Greg Hewgill. (Source)
GitHub repository
simavr is an AVR simulator using avr-gcc.
It already supports a few ATTiny and ATMega microcontrollers, and - according to the author - it's easy to add some more.
In the examples lies simduino, an Arduino emulator. It supports running the Arduino bootloader and can be programmed with avrdude through Socat (a modified Netcat).
You can unit test in Python with my project, PySimAVR. Arscons is used for building and simavr for simulation.
Example:
from pysimavr.sim import ArduinoSim
def test_atmega88():
mcu = 'atmega88'
snippet = 'Serial.print("hello");'
output = ArduinoSim(snippet=snippet, mcu=mcu, timespan=0.01).get_serial()
assert output == 'hello'
Start test:
$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok
I built arduino_ci for this purpose. Although it's limited to testing Arduino libraries (and not standalone sketches), it enables unit tests to be run either locally or on a CI system (like Travis CI or Appveyor).
Consider a very simple library in your Arduino Library directory, called DoSomething, with do-something.cpp:
#include <Arduino.h>
#include "do-something.h"
int doSomething(void) {
return 4;
};
You'd unit test it as follows (with a test file called test/is_four.cpp or some such):
#include <ArduinoUnitTests.h>
#include "../do-something.h"
unittest(library_does_something)
{
assertEqual(4, doSomething());
}
unittest_main() // this is a macro for main(). just go with it.
That's all. If that assertEqual syntax and test structure looks familiar, it's because I adopted some of Matthew Murdoch's ArduinoUnit library
that he referred to in his answer.
See Reference.md for more information about unit testing I/O pins, the clock, Serial ports, etc.
These unit tests are compiled and run using a script contained in a ruby gem. For examples of how to set that up, see the README.md or just copy from one of these examples:
A practical example, testing a Queue implementation
Another set of tests on another Queue project
A complex example, simulating a library that controls an interactive device over a SoftwareSerial connection as part of the Adafruit FONA library
The DoSomething example library shown above, used to test arduino_ci itself
I am not aware of any platform which can test Arduino code.
However, there is the Fritzing platform, which you can use to model the hardware and later on export PCB diagrams and stuff.
Worth checking.
We are using Arduino boards for data acquisition in a large scientific experiment. Subsequently, we have to support several Arduino boards with different implementations. I wrote Python utilities to dynamically load Arduino hex images during unit testing. The code found on the link below supports Windows and Mac OS X via a configuration file. To find out where your hex images are placed by the Arduino IDE, hit the shift key before you hit the build (play) button. Hit the shift key while hitting upload to find out where your avrdude (command line upload utility) is located on your system / version of Arduino. Alternatively, you can look at the included configuration files and use your install location (currently on Arduino 0020).
http://github.com/toddstavish/Python-Arduino-Unit-Testing
This program allows automated running of several Arduino unit tests. The testing process is started on the PC but the tests run on the actual Arduino hardware. One set of unit tests is typically used to test one Arduino library.
(this
Arduino Forum: http://arduino.cc/forum/index.php?topic=140027.0
GitHub project page: http://jeroendoggen.github.com/Arduino-TestSuite
Page in the Python Package Index: http://pypi.python.org/pypi/arduino_testsuite
The unit tests are written with the "Arduino Unit Testing Library": http://code.google.com/p/arduinounit
The following steps are performed for each set of unit tests:
Read the config file to find out which tests to run
The script compiles and uploads an Arduino sketch that contains the unit testing code.
The unit tests are run on the Arduino board.
The results of the test are printed over the serial port and analyzed by the Python script.
The script starts the next test, repeating the above steps for all test that are requested in the configuration file.
The script prints a summary showing an overview of all the failed/passed tests in the complete testsuite.
Keep hardware-specific code separate or abstracted away from the rest so you can test and debug that bigger "rest" on any platform for which you have good tools and with which you're familiar most.
Basically, try to build as much of the final code from as many known-to-work building blocks as possible. The remaining hardware-specific work will then be much easier and faster. You may finish it by using existing emulators and/or emulating devices on your own. And then, of course, you'll need to test the real thing somehow. Depending on circumstances, that may or may not be very well automatable (i.e. who or what will press buttons and provide other inputs? who or what will observe and interpret various indicators and outputs?).
James W. Grenning writes great books and this one is about unit testing embedded C code Test Driven Development for Embedded C.
I am using Searduino when writing Arduino code. Searduino is an Arduino simulator and a development environment (Makefiles, C code ...) that makes it easy to hack in C/C++ using your favorite editor. You can import Arduino sketches and run them in the simulator.
Screenshot of Searduino 0.8: http://searduino.files.wordpress.com/2014/01/jearduino-0-8.png
Searduino 0.9 will be released and a video will be recorded as soon as the lasts tests are done .... in a day or two.
Testing on the simulator is not to be considered as real tests, but it certainly have helped me a lot in finding stupid/logical mistakes (forgetting to do pinMode(xx, OUTPUT), etc.).
BTW: I am one of the people developing Searduino.
There is a project called ncore, which provides native core for Arduino. And allows you to write tests for Arduino code.
From the project description
The native core allows you to compile and run Arduino sketches on the
PC, generally with no modification. It provides native versions of
standard Arduino functions, and a command-line interepreter to give
inputs to your sketch that would normally come from the hardware
itself.
Also on the "what do I need to use it" section
If you want to build the tests, you'll need cxxtest from
http://cxxtest.tigris.org. NCORE has been tested with cxxtest 3.10.1.
If you want to unit-test code outside MCU (on desktop), check out libcheck:
https://libcheck.github.io/check/
I used it to test my own embedded code few times. It's pretty robust framework.
You can use emulare — you can drag and drop a microcontroller on a diagram and run your code in Eclipse. The documentation on the website tells you how to set it up.
Use Proteus VSM with an Arduino library to debug your code or to test it.
It is a best practice before getting your code onboard, but be sure with timings because the simulation does not run realtime as they run on the board.
Try Autodesk circuit simulator. It allows to test Arduino code and circuits with many other hardware components.
In basic Arduino is written with C and C++, even libraries of arduino are written in C and C++. So,in simple terms just handle the code as C and C++ and try doing the unit testing. Here, by the word "handle" I mean you to change all the basic syntax like serial.println to sysout, pinmode to varaibles, void loop to while() loop which breaks either in keystock or after some iteration.
I know this is little a long process and not so straight forward.On my personal experience, once you get to do with it, this turns to be more reliable.
-Nandha_Frost
In case you are interested in running an INO sketch and checkout the serial output, I have a working implementation of that in my Arduino NMEA checksum project.
The following script takes the file and uses Arduino CLI to compile it to a HEX file which is then loaded to SimAVR which evaluates it and prints the serial output. Since all Arduino programs run forever without really having an option of killing themselves (exit(0) doesn't work), I let the sketch run for a few seconds and then diff the captured output with expected output.
Download and extract Arduino CLI (in this case version 0.5.0 - latest at the time of writing):
curl -L https://github.com/arduino/arduino-cli/releases/download/0.5.0/arduino-cli_0.5.0_Linux_64bit.tar.gz -o arduino-cli.tar.gz
tar -xvzf arduino-cli.tar.gz
Now you can update the index and install the appropriate core:
./arduino-cli core update-index
./arduino-cli core install arduino:avr
Assuming your sketch is named nmea-checksum.ino, to get ELF and HEX, run:
./arduino-cli compile -b arduino:avr:uno nmea-checksum.ino
Next up, SimAVR to run the HEX (or ELF) - I build from source because the latest release didn't work for me:
sudo apt-get update
sudo apt-get install -y build-essential libelf-dev avr-libc gcc-avr freeglut3-dev libncurses5-dev pkg-config
git clone https://github.com/buserror/simavr.git
cd simavr
make
Successful compilation will give you simavr/run_avr which you can use to run the sketch. Like I said, timeout it otherwise it will never terminate:
cd simavr
timeout 10 ./run_avr -m atmega168 -f 16000000 ../../nmea-checksum.ino.arduino.avr.uno.elf &> nmea-checksum.ino.clog || true
The generated file will have ANSI color code control characters wrapping the serial output, to get rid of those:
cat nmea-checksum.ino.clog | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > nmea-checksum.ino.log
cat nmea-checksum.ino.log
Now all you need to do is compared this file to a known good file:
diff nmea-checksum.ino.log ../../nmea-checksum.ino.test
If there are no differences, diff will exit with code 0, otherwise the script will fail.