Convert Arduino Library To Netduino - General Discussion - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Convert Arduino Library To Netduino


  • Please log in to reply
18 replies to this topic

#1 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 07 April 2012 - 06:47 PM

I want to use the following library: http://ladyada.net/m...shield/use.html which makes it possible to use a lcd with only 2 digital pins. How would I change the library from c++ to c# Thanks
Steve


My Other Hobby: Engineer Turned Baker

#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 08 April 2012 - 07:14 AM

Hi smarcus3!

Porting C/C++ code to C# is actually much simpler than you might think. As for this project, start by creating a new Netduino project, then add two new empty classes:

Adafruit_MCP23017
Adafruit_RGBLCDShield

These two will act as wrapper classes for the code in the corresponding .cpp and .h files.

Now simply copy the contents of the .h and .cpp files into their respective C# wrapper class. Try to compile (will fail) and then go about correcting as many syntax errors as you can. In an .h file you would typically find class definitions, member declarations, method prototypes and constants whereas you will find the implementation of methods in the corresponding .cpp files.

Here's a few examples to get you started:

1. A constant definition as such:
#define MCP23017_ADDRESS 0x20
would translate into
public const int MCP23017_ADDRESS = 0x20

2. Simply delete all method prototypes like these ones, there not needed in C#.
void writeGPIOAB(uint16_t);
uint16_t readGPIOAB();

3. Types are easily converted and a pair of variable declarations like these two:
uint16_t var1;
uint8_t var2;
would become like so:
ushort var1;
byte var2;

4. Any C++ class method implementations like this one (using double colons):

void Adafruit_RGBLCDShield::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!}
Would translate into this C# method of the Adafruit_RGBLCDShield wrapper class

void home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}

In the context of porting, you can think of the C/C++ code as pseudo code and your job is to (1) figure out what the code actually does and then (2) convert that into its C# logical equivalent. Many times however, you'll find that large chunks of code will work after only minor changes and almost without any knowledge of what it does.

There might be include directives referring to standard C/C++ header files and/or libraries which can be a little tricky but usually you can replace those with an assembly reference and/or import directive.

Don't forget to study the original code licences and transfer those into your port but beware that some license models may not allow for modifications or porting. Always remember to give credit to authors(s) of the original code.

Hope this helps, good luck!

#3 65tux

65tux

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts

Posted 02 May 2012 - 11:00 AM

Did you ever get this working? Have the same hardware and a demo deadline fast approaching...

#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 04 May 2012 - 06:38 PM

Did you ever get this working? Have the same hardware and a demo deadline fast approaching...

I think he did:
http://forums.netdui...gmail-notifier/

#5 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 22 August 2014 - 04:02 PM

Do you mind helping me perform this as well?  Trying to convert over a couple of files and I have 271 errors.  I am sure as I start whittlign them down they will drop quick, but there are some I am not sure how to adjust.

 

Here is the setup and what I have done so far:

 

Converting LedControl.h and LedControl.css from an Arduino library to Netduino.

 

I am using Visual Studio 2012.

 

1)  I created a new project from scratch

2)  I right clicked on the project on the right and selected "Add" then "Class"

3)  I clicked "Code" under Micro Framework and named it LedControl

4)  VS2012 created a new file called LedControl.cs

5)  In the file was Namespace, then under that class LedControl {}
6)  Inside the brackets under "class LedControl", I copied the code from LedControl.h and after that added the code from LedControl.cpp
7)  I made the conversions mentioned above that I could directly match.

And this is where I am.  The main question is, was my process correct so far?  I am going to keep trying to clear errors to get the file to compile.

So far, I am getting a bunch of "Type Expected" errors.

My next question is, once I get this working, I call the library as it was called in the arduino code (not using the #include LedControl.h line)?



#6 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 22 August 2014 - 04:15 PM

Attached is the file I have created so far. I am going to keep plugging, and thank you for your help. I have also uploaded the program.cs file as well in case you need to see it.

Attached File  LedControl.cs   11.78KB   8 downloads
Attached File  Program.cs   1.66KB   2 downloads

#7 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 22 August 2014 - 08:09 PM

Ok, kept chugging and went back and re-read the instructions again. Found some items I missed (the LedControl:: that could be deleted from all the locations). I also went and cleaned up the code a little (formatting so I can follow where everything nests where).

I am down to 155 error from 271, so making progress.

The big one I am having trouble figuring out is the "type expected". One of these instances the code is:

public const int OP_NOOP = 0

So I figured I'd try just getting rid of the "const" to see if that would fix it, making it:

public int OP_NOOP = 0

and no luck. So I am guessing it has to be something to do with the "public" and a declaration above somewhere (or lack of declaration).
 
***************************EDIT*******************************
Ok, so a little more work and I am down to 15 errors,  WOW!  apparently most of the errors were around the byte created.
 
Originally it was:
 
 
const static byte charTable[128] = {};
 
but after looking at some other code, i changed it to:
 
 
byte[] charTable = new byte[128] {};
 
and that made a WORLD of difference.
 
Still working on the "type expected and a new one "invalid token".

********************Latest Update***************************
Instead of making a new post every time I figured I'd just edit the last one.

OK, got LedControl.cs to pass compile, except for 12 errors. They are:

Type 'Dome_Controller_Arduino_Port.LedControl' already defines a member called 'LedControl' with the same parameter types

(it is 12 occurences of this, each member is a different name).

Attached File  LedControl.cs   13.55KB   4 downloads
Attached File  Program.cs   1.91KB   2 downloads

So I added the latest versions here for people to look at.

Any and all suggestions are greatly appreciated.

#8 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 24 August 2014 - 03:15 PM

OK, got LedControl.cs to pass compile, except for 12 errors. They are:

Type 'Dome_Controller_Arduino_Port.LedControl' already defines a member called 'LedControl' with the same parameter types

 

You have left empty function declarations in your C# class - this is valid in C/C++, where you can have empty function declaration (in .h) and then implement in at different place (.cpp), but not allowed in C#. Delete all empty functions at the beginning of the C# file, where you have the class declaration from C++ header.



#9 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 25 August 2014 - 12:12 PM

Thanks CW2.  Up side, that fixed those errors.  Down side, when I cleaned them out, I got about 100 more.  But such is the fun of cleaning code.



#10 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 25 August 2014 - 11:46 PM

182 errors to be exact. WOW. I have uploaded the code here for people to look at. One of the errors is:

The name 'B01111110' does not exist in the current context

That name is in an array that is created in the file. I am not sure why it is erroring. In fact, the above error accounts for 133 of the 182.

Any thoughts would be greatly appreciated.

Attached File  LedControl.cs   12.33KB   4 downloads
Attached File  Program.cs   1.92KB   3 downloads

#11 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 26 August 2014 - 06:32 AM

The name 'B01111110' does not exist in the current context

 

C# does not support binary literals - you'd have to either define those Bxxx constants like

 

const byte B01111110 = 0x7E;

const byte B00110000 = 0x30;

...

 

or use the hex literals directly, i.e. instead of B01111110 write 0x7E.



#12 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 26 August 2014 - 03:03 PM

Gotcha. Just converted all the occurrences, and went from 182 down to 50. making progress!!!

Now I am getting a bunch of "the name ______ does not exist in the current context."

Attached File  LedControl.cs   11.69KB   3 downloads
Attached File  Program.cs   2KB   3 downloads

#13 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 26 August 2014 - 04:18 PM

Now I am getting a bunch of "the name ______ does not exist in the current context."

 

Well, those are Arduino library function calls and some constants - the good news is you don't need to convert that, just implement spiTransfer() function to call .NET Micro Framework SPI.Write() method and delete all pinMode(), digitalWrite() etc. calls, which are not needed (because SPI class does that internally; including the ChipSelect pin if you set it in the configuration).



#14 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 27 August 2014 - 01:19 AM

OK, going back and looking, most of my errors are due to commands such as "MSBFIRST" and "ShiftOut" that seems to be built in Arduino commands, but not native to C#.

The files above are the most up to date so far. I think I am out side where I can figure this out on my own. Gonna need some help or guidance on how to convert those commands.

Thanks guys!

#15 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 27 August 2014 - 01:24 AM

Well, those are Arduino library function calls and some constants - the good news is you don't need to convert that, just implement spiTransfer() function to call .NET Micro Framework SPI.Write() method and delete all pinMode(), digitalWrite() etc. calls, which are not needed (because SPI class does that internally; including the ChipSelect pin if you set it in the configuration).


Sorry CW2, I missed your reply before I commented back. Gonna look at what you suggested. Thank you!

Followed your advice, and down to 38 errors now.

Getting a "Best overload method" error and a "can't convert int to byte (etc)" error. The latter I get. I need to go through and make sure that all my bytes are directed to bytes, and all my ints are directed to ints. But I want to make sure the other errors aren't causing the "convert" errors.

#16 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 27 August 2014 - 01:53 AM

C# does not support binary literals - you'd have to either define those Bxxx constants like
 
const byte B01111110 = 0x7E;
const byte B00110000 = 0x30;
...
 
or use the hex literals directly, i.e. instead of B01111110 write 0x7E.


Also, to keep track of the changes, I followed your suggestion and rewrote all the Bxxxxxxxx to 0x##. Looks much better and cleared out TONS of errors.

#17 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 27 August 2014 - 07:08 AM

Well, how should I put this... the whole LedControl code is basically one SPI.Write() method call to transfer 16 bit data (spiTransfer() function) to the MAX and a few methods that set the data to perform the desired command.
 
Personally, I would stop converting the Arduino code and start with C# from scratch, using the device datasheet as reference and the Arduino code if in doubt (assumed to be working). There is also possibility that the converted code will not work at the first try, so you'd need to troubleshoot it, and it is much easier to troubleshoot code you understand well (e.g. written yourself).
 
Create a new project and start talking to the MAX using the SPI class, it should be something like this: 

...
public static void Main()
{
  var max = new SPI(new SPI.Configuration(...));
  var data = new byte[2]; // 16 bits (address + 8 bit data)

  // Display test mode
  data[0] = 0x0F; // Address
  data[1] = 0x01; // Test mode on

  max.Write(data);

  Thread.Sleep(Timeout.Infinite);
}

Once you get the code working (written from head, so probably does not even compile, data buffer can be ordered the other way round etc.), you can add command constants and wrapper methods, then you will be able to use the Arduino code because you'll see what it does and where it fits.



#18 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 27 August 2014 - 01:01 PM

Well, how should I put this...


(in all good humor, no ill will) just call me an idiot and slap me up side the head....LOL!!!!

I understand what you are saying, and I think I have decided to jump in feet first into a project that is fairly (fairly? I'd say VERY) in depth.

I am trying to learn as I go, and while I can create and code simple projects (I have done some random LED flashes, random servo movement, and other simple input/output commands) more complex concepts such as SPI and "data" transfers elude me at this time. So I have been trying to learn how to control the MAX7219's and I have been able to understand the concept of HOW it works (if doing more than 1 chip, turn on CS pin, send (1) 8 byte word, sends a second 8 byte word (a word for each chip), then turn off CS and the chip does the work) but it is the actual implementation I am struggling with. I have found a couple of tutorials on the chip vs Netduino on various websites, but they all seem to control 1 chip and then go "OK, that is how you do it. But the great thing is this method stacks chips and you keep adding on if you need more." and they never discuss the "adding on".

I was able to find one project that used the bitbang method to control more than one, but the problem is once, I got above 2 chips, I didn't need a Thread.sleep() line to slow down the output. It was THAT SLOW. If I try to control 4 or more chips, refresh rate nears once per second if not slower.

I found a project that uses the extendedSPI and has the datasheet built into the CS files, but I am having serious difficulties locating the line (or lines) that controls the CS pin that allows for multiple chips. The refresh rate on the extendedSPI project is awesome, but all chips output the exact same display.

That is what started my search in the Arduino realm and wen I came across the library I am working on here. The code seemed very simple. Load the library, tell it how many chips, then use one of a few commands to write to the display and done. But what I may have thought would be a simpler fix, has definitely shown not to be such.

#19 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 27 August 2014 - 02:02 PM

Unfortunately, I don't have any MAX7219, but it seems to be fairly easy to operate the cascade:

  • Connect all LOAD/!CS inputs together (to Netduino pin used as SPI CS),
  • Connect MAX DOUT to DIN to chain the devices.
[Netduino] MOSI -> DIN [ Max#1(16 bits)] DOUT -> DIN [Max#2(16 bits)] DOUT -> ...
           CS ------------- LOAD/!CS ------------------- LOAD/!CS

Note: The clock (SPI CLK) signal is omitted for sake of brevity, it must be connected together.

That means the cascade behaves like one N×16 bits register. So, when you send 16 bits to the first Max#1, the contents of its internal 16 bit register is shifted out to the adjacent device, whose contents is shifted out to the adjacent device (if any) etc. (you can connect DOUT to Netduino MISO and you can receive the data back, which is often useful - this way you can detect the number of  chained devices in runtime).
 
To operate the cascade, you simply send N×16 bits of data (N×2 bytes) and control all MAX ICs at once. If any of the 16 bits have address zero, i.e. the NO-OP command, the corresponding MAX does nothing and appears as skipped - which enables you to control only selected device(s).
 

var maxChain = new SPI(new SPI.Configuration(...));
var numberOfDevices = 2;

var data = new byte[numberOfDevices*2];
// Important note: The following order is most likely wrong,
// too lazy to think about it...
data[0] = 0x01; // Max#2 Data
data[1] = 0x0F; // Max#2 Address
data[2] = 0x00; // Max#1 Data
data[3] = 0x00; // Max#1 Address

maxChain.Write(data);





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.