Any interest in running arduino code on PC, partially?

I am referring to running hardware-independent components of your code on PC, such as a class that handles some data in your arduino, and calculate, export strings or make decisions with the data. This could be as easy as interpreting serial data and assign values to variables or making actions. In my case, I have a schedule class that handles schedule items. An instance of a schedule could have a few items such as MTWHh 2pm-2:50pm, feed college students with hard science. I would want to use this class to generate output that can be rendered into a menu on an LCD. Testing this code involves uploading, finding problems, going back and uploading... There is no debugger on arduino IDE so in case there's a problem, I'm down to serial.println() :frowning:

What I have been exploring today was to compile and run this class, which is hardware independent, on Dev C++ for windows. I have got some success to run this class and use printf (oh yeah!) to output to console to see if the class generates the right menu. And I'm using a debugger. It's nice.

I even mocked up PROGMEM related typedefs, functions, etc to run PROGMEM definitions and functions (not fully tested) on PC.

With the windows console_buffer_status_info stuff I found on the net, I'm thinking about making a LiquidCrystal class to output directly to the console. This will be very nice for everyone interested in developing user interface with an LCD. The input can be taken from keyboard with a modified version of my phi_interfaces, treating the keyboard as a serial keypad. Then my entire phi_prompt Text based user interface library can be run and debugged on PC.

Is this something anyone is interested in? I read the last 10 pages and all I found, remotely related to this thread, were arduino simulators. This is not a simulator, rather a "trans-planter" of some sort instead.

I had to hack up an Arduino.h and fake a bunch of strXXX_P functions for PROGMEM access.

Maybe next step is to mock up serial and LiquidCrystal and then I can directly port my phi_interfaces library to use PC keyboard as input buttons. Now I am really starting to appreciate my own work a bit more than cursing bugs all day, since I can debug with a real debugger instead of chasing my own tail in the arduino memory. With the windows protection, I even caught a few array out of bound stuff that I didn't catch in arduino IDE, since there's no segment protection in arduino SRAM :slight_smile:

I did something similar years ago when I had to write the code for a system before the hardware interface panel was available. It ran on my computer of the day (BBC/Microbee/Sorcerer, I can't remember) with 2 or 3 low-level putchar/getchar functions. Then when the hardware was ready a quick rewrite of those funcs was done and viola it worked on the hardware.

This was a fairly complex UI so it was very useful to debug on a better machine without the compile/download cycle, and anyway I didn't have the hardware so there was no choice.

For a simple display it wouldn't be worth the effort I think but to debug something more complex it could be very useful.

I have seen LCD emulators that run somewhere, maybe with AVR Studio or something, I can't remember where.

I suppose the question may be, how many people are writing complex LCD display code? Is there enough to make the effort worth it?


Rob

Off course the ultimate is being able to debug on the arduino itself. However there will always be limitations (like no debug support) which make the simulator second best. However there are currently no good (affordable?) simulators.

So yes I have been porting (This is the official term) Arduino code to the PC, like you have. This purely for debugging purposes and only for "not really arduino oriented code". The biggest pain I have is the arduino and AVR defined variables.
Do not include Arduin.h and you get problems with PROGMEM and many others. Do include Arduino.h and you have problems with stuff you don't need.

Conclusion: I am interested in a Arduino.h ported to PC world.

Best regards
Janje

Rob,

I see! I'm doing the same, just several decades later!

Jantje,

Here is a link to a thread where I outlined how to modify Arduino.h to include what you want and leave the rest out of the picture:

http://arduino.cc/forum/index.php/topic,96058.msg722168.html#msg722168

I simulated the PROGMEM functions, which is not yet posted. I'll post tonight. With the "simulation", you should be able to copy strings you defined as PROGMEM from arduino to Dev C++ and use the simulated functions to operate on them, such as strcpy_P an strlen_P. The strings are stored on PC RAM of course. You just don't have to modify your PROGMEM stuff anymore when copying your code to Dev C++. Interested?

Sure I'm interested.
Can you share the modified Arduino.h directly?
Best regards
Jantje

Jantje:
Sure I'm interested.
Can you share the modified Arduino.h directly?
Best regards
Jantje

Will post the file on this thread. We can both test it. BTW, what IDE are you using right now? I'm using Bloodshed's Dev C++

I'm using eclipse
Using my eclipse plugin I can have all code in one place :slight_smile:
Best regards
Jantje

I'm not familiar with eclipse. Does it come with gcc or other flavor of c compiler?

Eclipse does not come with gcc. Eclipse is development language neutral.
Even CDT that is the C/C++ extension for eclipse; does not come with gcc
But arduino does :slight_smile: so you have gcc on your system and eclipse can integrate with that one.
Best regards
Jantje

Here you go! I've also implemented a LiquidCrystal class. Unzip all files in your default include folder. Make a windows console project and use my main.cpp as a template. At the moment it runs a fake LCD sample program to report millis() :slight_smile:

Help me break them! Everything seems to work until another programmer takes a look :wink:

main.cpp (633 Bytes)

Arduino.zip (9.95 KB)

A list of working (until proven broken!) Arduino functions:

millis();
microSeconds(); //Good luck with this on a multitasking operating system!
delay();

//PROGMEM related functions. Be careful with this though, many pitfalls may exist
strcpy_P();
strlen_P();
pgm_read_byte();
pgm_read_word();

//LiquidCrystal library. Will work on write(char), print(int) and print(float)
begin();
clear();
print(char*);
print(char);

//Will work to port phi_prompt user interface library and its physical layer phi_interfaces to PC

liudr
Your example worked right out of the box XD
As predicted mine did not ]:smiley:
So I did some code changes. I reintroduced avr/pgmspace.h because it declares many types I use regularly.
I also created a class called ConsoleSerial that I mapped on Serial Serial1 Serial2 and Serial3. This class can not read data (it wil say the buffer is empty) but it dumps all the Serial.prints to the stdout 8)
I added String and some other stuff.
My AES test sketch works now on PC 8) (only some extra includes were needed) It is a perfect example of why you would use this code. There is no Arduino specifics in doing AES encryption.
The sketch needs the unmodified AES library (http://arduino.cc/forum/index.php/topic,88890.0.html) and your updated code (attached) and the sketch code (below).
Works great. Thank you.
Back to you to say it ain't working on your side 8)
Best regards
Jan

#include <Arduino.h>
#include <LiquidCrystal.h>
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include "AES.h"

using namespace std;


#define KEYLENGTH 32
AES aes;
char PassString[] = "This is hard to believe but true however";// this must be at least KEYLENGTH characters long
byte key[KEYLENGTH];
void setup()
{
	Serial.begin(115200);

	Serial.println("Starting AES test");
	for (int i = 0; i < KEYLENGTH; i++)
	{
		key[i] = PassString[i];
	}

	if (aes.set_key(key, KEYLENGTH) != 0)
	{
		Serial.println(F("Failed to set key"));
	}
}

// The loop function is called in an endless loop
void loop()
{

	char Message[] = "A top secret message. 123456789012345678901234";
	byte plain[N_BLOCK];
	byte cipher[N_BLOCK];
	byte decrypted[N_BLOCK];

	Serial.print(F("message : '"));
	Serial.print(Message);
	Serial.println(F("'"));
	Serial.print(F("plain binary: '"));
	for (int i = 0; i < N_BLOCK; i++)
	{
		plain[i] = Message[i];
		cipher[i] = 0;
		decrypted[i] = 0;
		Serial.print(plain[i]);
	}
	Serial.println(F("'"));

	Serial.print(F("plain char: '"));
	for (int i = 0; i < N_BLOCK; i++)
	{
		Serial.print(char(plain[i]));
	}
	Serial.println(F("'"));

	if (aes.encrypt(plain, cipher) == 0)
	{
		Serial.print(F("encrypted : '"));
		for (int i = 0; i < N_BLOCK; i++)
		{
			Serial.print(cipher[i]);
		}
		Serial.println(F("'"));
		Serial.print(F("encrypted hex : '"));
		for (int i = 0; i < N_BLOCK; i++)
		{
			Serial.print(cipher[i],HEX);
		}
		Serial.println(F("'"));
	Serial.print(F("encrypted char: '"));
	for (int i = 0; i < N_BLOCK; i++)
	{
		Serial.print(char(cipher[i]));
	}
	Serial.println(F("'"));
	} else
	{
		Serial.println(F("Failed to encrypt"));
	}

	if (aes.decrypt(cipher, decrypted) == 0)
	{
		Serial.print(F("decrypted binary : '"));
		for (int i = 0; i < N_BLOCK; i++)
		{
			Serial.print(decrypted[i]);
		}
		Serial.println(F("'"));

		Serial.print(F("decrypted char : '"));
		for (int i = 0; i < N_BLOCK; i++)
		{
			Serial.print(char(decrypted[i]));
		}
		Serial.println(F("'"));
	} else
	{
		Serial.println(F("Failed to decrypt"));
	}

	delay(1000);
}

arduino.zip (23.3 KB)

Alright! I'll be adding some more LiquidCrystal features too.

Jantje:
However there are currently no good (affordable?) simulators.

Jantje, have you tried this Simulator. There are two versions - a free version code limited to 100 lines and with a 30s delay on opening a sketch (increments by 1 each time a new sketch is opened) or an unlimited version for $6.99. We have had a lots of downloads Of the Free Version and around 10% choose to upgrade to the Pro Version. We have added a lot of features but there is still lots to do - such as adding custom libraries, structures and pointers.

With LCD, we have a lot of support for this and can run all the Arduino LCD Examples. The only issues here are support for 4line LCDs, accurate representation of 128 byte Hd44780 (or compatible) memory, and CGRAM. There should be some examples of LCD simulation on our Youtube videos.

Building a Simulator is very hard work and if we knew how much effort it would take, we probably wouldn't have started but there was little else around. Converting the Simulator to an Emulator could reasonably simple, if the Arduino compiler could add a simple getchar() routine between source lines, but this is more a question for the Arduino team. I am sure there will be an Arduino Emulator soon, probably sooner if more people request this.

Anyway, let us know if you want to collaborate. We were thinking of maybe adding some COM routines so that another program (such as a Shield Emulator) could receive Arduino output data in SPI,Wire,Ethernet,Serial, LCD or other interface. We have also been asked if a Simulator.dll is possible so that the Simulator can be externally extended.

Shields_Arduino:
We have added a lot of features but there is still lots to do - such as adding custom libraries, structures and pointers.

That is what I mean with no good simulators. I always use custom libraries and mostly use structures and pointers.
So your simulator is good enough for learning and understanding but not for a debugging a real application.
I do hope it will be one day.
Best regards
Jantje

Same here. We are testing emulator, not simulator. If what we do (non-hardware related code) can run on PC, it will be much easier to debug and port back to arduino hardware. It's good to know though that you have a simulator in a good shape already. This will come in handy when time-critical things needs to be simulated and slowed down for developers to see what's going on.

I made some additional functions for this simulated environment by adding a DS1307 class. The class was created by Matt Joyce (matt.joyce@gmail.com). I took its shell and bashed in windows stuff. Nice to see the PC time change from my simulated environment running phi_prompt menus and lists.

New list of working pieces:

millis();
microSeconds(); //Good luck with this on a multitasking operating system!
delay();

PROGMEM related definitions and functions. Seems to be working with "c-strings in PROGMEM and a pointer array in PROGMEM to point to these strings". I have not tested other data types. Be careful with this though, pitfalls may still exist
strcpy_P();
strlen_P();
strlcpy(); // This is only available with GNU C not a standard one but I need it.
pgm_read_byte();
pgm_read_word();

LiquidCrystal library. Will work on write(char), print(int) and print(float)

Everything except for below functions, which I don't use
void noDisplay(); ///< Turns off the display
void display(); ///< Turn on the display
void scrollDisplayLeft(); // Hate these scroll functions. Useless
void scrollDisplayRight();
void leftToRight();
void rightToLeft();
void autoscroll();
void noAutoscroll();
void createChar(uint8_t, unit8_t*); // I can't create char on PC

DS1307 all working except for this one I didn't implement. Easy to do though. Also start and stop have no actions. You can't change DOW without changing dates.
int get(int, boolean);

phi_interfaces input device library only has the phi_serial_keypads class which takes inputs from keyboard. Function keys are wsadfg of course (who didn't play some FPS games?)

phi_prompt user interface library works except that the right arrow looks different and the scroll bar is not as awesome as on real LCD

Will attach code and a sample once I get one done.