3

I have an arduino program that only does serial communications with a little bit of math, and I am writing another one to communicate with it on a second arduino. For testing purposes I was hoping I could run the serial only program on my desktop. I know it is possible to run on a raspberry pi but I have never done that. Can I do something similar on windows? If not, can anybody recommend the easiest way to do this with a regular C++ program that would require very little editing? Here is a copy of my code if it's helpful. It basically increments a variable up and down between 0 and 100.

int pos = 60;
bool flag=0;
int dly=50;
int vel=0;

const int buttonPin =  12;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status


void setup() {
  pinMode(buttonPin, INPUT_PULLUP);

Serial.begin(115200);
}

void loop() {
    dly=50;
    buttonState = digitalRead(buttonPin);
    if (buttonState==0)dly=12;
    Serial.print(vel); //speed
    Serial.print(",");
    Serial.println(pos); //position
    delay(dly);
    if (pos==30)flag=1;
    if (flag==1) pos+=1;
    if (pos==100)flag=0;
    if (flag==0) pos-=1;
    vel=1000/dly;
    if (flag==0) vel*=-1;



}
2
  • try processing ... processing.org .... look for example sketches that do serial comm ...
    – jsotola
    Commented Apr 30, 2020 at 23:50
  • I'm familiar with processing. The goal for me is to just have one program that I can run in two places. Otherwise I can just use python or another Arduino. Commented May 1, 2020 at 0:21

3 Answers 3

3

If you want to run the Arduino sketch on your desktop, you just have to implement the Arduino core library for your PC.

It may not be as bad as it sounds. If your program makes only minimal use of the Arduino core, you may implement only the parts you really need. For example, this partial implementation is enough to run your program:

#include <cstdint>
#include <iostream>
#include <unistd.h>  // for usleep()

using std::cout;
using std::endl;

#define INPUT_PULLUP 2

void pinMode(uint8_t, uint8_t) {}

uint8_t digitalRead(uint8_t) { return 0; }

void delay(int t) { usleep(t * 1000UL); }

struct {
    void begin(int) {}
    template<typename T> void print(T x) { cout << x; }
    template<typename T> void println(T x) { cout << x << endl; }
} Serial;

int main()
{
    void setup();
    void loop();
    setup();
    for (;;) loop();
}

I tested this on Linux, by simply appending your program right below this. If you are using Windows, you will have to replace the usleep() function with the appropriate Windows call (and <unistd.h> with the appropriate header). The serial stream goes to the standard output. You may redirect it to the USB serial port if you wish (trivial to do in Linux, I assume it should be doable on Windows). You may also want to replace digitalRead() with something that simulates a more realistic user interaction.

Keep in mind that the sizes of the basic data types can be different on the Arduino and on the PC. On an AVR-based Arduinos, int and pointers are 16 bits while long is 32 bits. This is an “IP16” data model. An ARM-based Arduino would typically be ILP32, whereas a 64-bit PC is LP64, unless it runs Windows, in which case it's LLP64. This can make a difference, especially if some of your calculations are prone to overflow with the smaller data models.


Edit: I recently stumbled upon NCORE, a native core for Arduino. It may be a good fit for what you are trying to do. From the page 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 interpreter to give inputs to your sketch that would normally come from the hardware itself.

2
  • This might be the way to go about it. I'm just curious why all this is required for a desktop, but I can run an ino file on a raspberry pi without it. Commented May 1, 2020 at 0:23
  • @bobmcgrath: I guess someone has already implemented a quite complete Arduino-compatible core for the Raspberry... WiringPi maybe? Commented May 1, 2020 at 9:36
0

It depends on what exactly you wanna test. I guess you want to run the "Serial & math only" sketch on the PC, while communicating over Serial (via USB) with the other real Arduino. It can be done, but you would have to change quite a lot. The Serial libraries for a PC are different than for an Arduino. Also you cannot simply compile Arduino code for a PC, they are totally different devices.

Mostly the Serial code is better tested with the real hardware, by checking, what actually is send. You can do this by connecting to the Arduino over Serial/USB with a corresponding program (Arduino Serial Monitor, Putty, ...), so that you can test the functionality by hand. Or write a simple test sketch for the second Arduino.

For testing the math part, you could relatively easy write a so called unit test on the PC. A unit test tests a confined code part without or only with few dependencies. Most math is the same on Arduino and PC (as long as you use variables of the same size and type). So you could put all the math code into a function, which does not contain Arduino specific code, like Serial code. Just the math. Then you can copy that function into the source code of a C++ PC programm and use it, to test the math function unit without involving the Arduino.

A further option would be using an Arduino Simulator. But keep in mind, that these simulators can never be as good as the real hardware and you can see differences in the behavior of simulated and real Arduinos. Though it should work, as long as your program is simple and does not rely on too much outer hardware or events. Your current program is simple enough, so that a simulator should be able to work with it.

All in all: Testing your code outside of the real Arduino mostly only makes sense, when you have a complex program, that does not involve Arduino specific code, which would need the hardware to work. If your project is not very complex, you are mostly better off with testing directly with the real hardware.

0

There is also arduino_ci, a framework for running unit tests against an Arduino library (maybe also sketch) on your computer. It contains mock implementations of most Arduino functions and some libraries, and gives the unittest control of things like Serial buffers and I/O pin values.

For your example, you could maybe write a unittest that just use stdin/stdout as a serial port and then connect two of these programs together, or maybe you could generalize your communication code a bit into an object and then instantiate that twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.