Arduino blog

Arduino blog

Arduino thinkering

This blog is about things I come by related to Arduino which I feel are inspiring/important/funny enough to write about.

Controlling Arduino over the web: Blinking a led the cool way. Part 3:Connecting dots

Arduino sketch experiancesPosted by Jan Tue, March 24, 2015 13:55:32
Preface:

If you have not yet read the blog post Controlling Arduino over the web: Blinking a led the cool way. Part 1&2; please read them first.

What you will learn in this post:

In the previous post we add my blinkled library to make a led blink based on serial input.
The point of this post is to change the blinking rate using the serial in a generic way. In other words we want to get rid of the string parsing in the loop() method of the previous example.

I consider this a steep slope learning curve to understand what is going on. To use it; it is a lot easier.

Here is a link to the sample program this article is about.

Lets get started:
Even after two introductory blogs I still find it hard to find the best entry to explain how I do it. So lets start with what you probably think is the most interesting: "What do I need to do to get it to work."
From a conceptual point of view: What are the steps needed to automate changes to variables via the serial port?

1) A list of the variables you allow access to including the access type.(further on called list)
2) Code to register variables to the list. (further on called serialRegister)
3) A component to control the serial port that uses the list to communicate with the serial port and changes values in Arduino memory. (further on called SerialCommunicator)

The list: conceptually
The list has to contain all the information the SerialCommunicator needs to get his job done.
It needs a pointer to the variable so it can change/read it.
It needs a name so it can be referenced to via the serial communicator.
It needs access control flags so we can have read only objects and read/write objects.
It needs the type of the object so we can convert the text to the correct memory content to write to the pointer.

The DUMP serial command actually dumps the list and the memory values the list points to. Lets look at the partial dump of Marvin my mowrobot for a nice example.

Marvin has a temperature sensitive resistor in a voltage bridge connected to a ADC pin of the Arduino. Arduino calculates the Celsius as follows
Celsius=(ActualReadValue*MultiplyerValue)/1000+Offset;

name RobotSensors.mow_temp.Left.Celsius
modflag 0
Type int16_t
Value 20

name RobotSensors.mow_temp.Left.ActualReadValue
modflag 0
Type uint16_t
Value 0

name RobotSensors.mow_temp.Left.MultiplyerValue
modflag 3
Type int16_t
Value 6747

name RobotSensors.mow_temp.Left.Offset
modflag 3
Type int16_t
Value 20


Lets go into the dumped fields:
The name is a concatenation of names. I map my class instantiations on the name (it is not necessary to do so). In other words I have a class instantiation RobotSensors which holds a member called mow_temp which holds a member Left which holds the members Celsius, ActualreadValue and MultiplyerValue.


modflag is a collection of binary orred values. The first bit means write the second bit means save (more on save in a later post)
The ActualReadValue is the value arduino returns from the analogRead method. Therefore I do not allow to change the value and modflag is 0.

type: I store the value in a unsigned int so type is uint16_t

value: is 0 as the last analogread before the dump returned O.

Because MultiplyerValue and Offset have the write attribute you can change the value of those while Arduino is running to tune the value of Celcius on the fly -over the web-. Isn't that cool?


serialRegister: conceptually
Registering is adding a value to the list. You should register all your fields in the setup() routine. For each field you have to register the name, the mod flag, the type and a pointer to the variable.


SerialCommunicator: conceptually
The serial communicator needs to take control over the serial port. This means you can no longer use the serial port as an input device as the Serial communicator is already reading the serial port.
You can however write to it because the SerialCommunicator only writes in his loop() method and will not exit the loop() when the write is unfinished.
Further on the serial communicator must be capable to convert memory variables to a textual representation and the other way around.
The serial communicator must be able to search the list to find the field to modify.
The serial communicator must be capable to report error conditions and feedback actions.
The serial monitor must guard that the read/write rules are respected.

This is a whole lot. But the good news is... The serialCommunicator is a library you can download.






Now we know what the big parts are lets see how to implement them.

list: implementation
I implemented the list as an array. (apart from array I did lots of thinking, considerations and implementations which are out of scope of this article) This means you have to declare an array and assign a size to it. The size of the array is a bit of a pain-point as you have to make it big enough to get all fields into it but you only know how many fields you have when you have compiled and run the code.
This is why the list is actually visible 2 times in the sample program. Once to declare the variable and once to check the size
#define MAXFIELDS 70
FieldData AllFields[MAXFIELDS];
.....
//As MAXFIELDS needs to be big enough it is not a bad idea to know how big it is now
SerialOutput.print(F("Current memory fields "));
SerialOutput.println(lastFieldIndex); //yes I do use global variables
SerialOutput.println(F(" from "));
SerialOutput.println(MAXFIELDS); //13 of 70 that is way more than enough

As long as you have enough fields in the list you can forget about it.


serialRegister implementation
note: Until now I only talked about field names. However in the code I make a distinction between the class and the field. Field is everything after the last dot (commonly called leave) and class is everything before the last dot. -see the F macro why I did so-

The methods to register a field in the list are called set and setnext. The difference between the 2 is that setnext assumes the class parameter is the same as the previous call to set.
Lets look at the serialregister of led13
void BlinkLedSerial::serialRegister(const __FlashStringHelper* Name)
{
FieldData::set(Name, F("OnInterval"),MOD_WRITE|MOD_SAVE,&myOnInterval);
FieldData::set(Name, F("OffInterval"),MOD_WRITE|MOD_SAVE,&myOffInterval);
FieldData::set(Name, F("LedState"),0,&myLedState);
FieldData::set(Name, F("PreviousMillis"),0,&myPreviousMillis);
FieldData::set(Name, F("LedPin"),0,&myLedPin);

}

You see I register 5 fields for the led.
I'm using C++ overloading to get the correct type from the pointer. This makes the code far more reliable.

As I use globally instantiated classes and I wrap all the set(Next) calls of a class in the serialRegister method; I mostly only need to call serialRegister for each globally defined class instantiation in setup() to create the whole list.
Just like in the sample program
myCommunicator.serialRegister(F("Admin"));
led13.serialRegister(F("BuildInLed"));

SerialCommunicator: implementation
I implemented the SerialCommunicator but that does not mean there is nothing to do for you.
One thing I like to know about my sketches running on a arduino is: What sketch is running? Therefore the dump command starts as follows:
Dumping all fields
SketchName MaaiRobot
CompileDate Aug 16 2013

The code can find out the compile date but the SketchName is something you need to provide. Here is how:
const char mySketchName[] PROGMEM="Serial Communicator step3";
The second thing to know is that the SerialCommunicator has a serial register that is probably very interesting to register. I (nearly) always register him first.

Loop()
This is what the loop looks like in this example
// The loop function is called in an endless loop
void loop()
{
// yes!!!! yes!!! That is all we need in the loop to change the blinking of the led
myCommunicator.loop();
led13.loop();
}


Really, nothing more is needed. Isn't this easy to maintain?
Compile the sample, upload and play with it using the serial monitor.
Have fun
Jantje



What is that with the F macro and PROGMEM..?
(or about strings and memory usage)

As you are probably aware the Arduino has very little memory. The architecture of the AVR also makes that "memory" is not one big thing but it exists out of "program memory" and "real memory".
The "real memory" is what you are likely to run out first. Using char arrays increases that process. Using compiler directives you can direct the compiler to only use "program memory" this means you need special routines to read the char arrays. You can not write to program memory char arrays.

Arduino implemented the F macro (as far as I know: no pun intended) and __FlashStringHelper to help arduino programmers out. The PROGMEM is a gcc fix.
I'm using this technique to save memory but -due to the no write rule- it has some drawbacks: like the artificial set and setnext and classname and fieldname. The reason is that you can not add 2 PROGMEM/F char arrays and put them in a PROGMEM/F char array.




  • Comments(2)//blog.baeyens.it/#post18

Controlling Arduino over the web: Blinking a led the cool way. Part 2:blinkled

Arduino sketch experiancesPosted by Jan Sat, January 10, 2015 19:19:04
Preface:

If you have not yet read this blog post Controlling Arduino over the web: Blinking a led the cool way. Part 1:SerialStringReader please read it first.

What you will learn in this post:

In the previous post I discussed the SerialStringReader to read line by line from the serial port.
In this post we add my blinkled library to make a led blink based on serial input.
The point of this post is to get a better understanding of the way I Use classes with setup() and loop().

I consider this a low slope learning curve. The next one will be steep.

Lets get started:


Yes blinking a led is cool. But controlling the on/off rate is cooler. You can do this with 2 potentiometers (one to control the off time one to control the on time) .....but we want to get to web control. Controlling a potentiometer over the web is not exactly easy. We need another way in.

Controlling over the serial port is more ready for the web. Therefore in this example we will use the SerialStringReader to control blinkled directly.

We will use "fixed line commands" to control the blinking of a led.

Note that the code is purely for learning purposes and in no way my advised way.



So here is the code

#include "SerialStringReader.h"

#include "BlinkLed.h"

//for the stream you want to read info from you need to declare a SerialStringReader

//you can only have one

SerialStringReader myCommunicator;



//Define that the USB serial (pin 0 and 1 on the uno) is to be used by the mySerialReader

//If you want to use the yun with the bridge use Serial1

#define THESERIAL Serial

Stream &SerialInput = THESERIAL;

Stream &SerialOutput = THESERIAL;



BlinkLed led13(13,500,2000);

//The setup function is called once at startup of the sketch

void setup()

{

delay(2000);

THESERIAL.begin(115200);

SerialOutput.println("serialStringReaderDemo2");

led13.setup();

myCommunicator.setup();

}

// The loop function is called in an endless loop

void loop()

{

myCommunicator.loop();

led13.loop();

if (myCommunicator.messageReceived())

{

SerialOutput.println("You have send a message to Arduino.");

SerialOutput.println("And the message is:");

char * message=myCommunicator.getMessage();

SerialOutput.println(message);

if (strcasecmp(message,"LED SLOW")==0)

{

led13.setOnInterval(5000);

led13.setOffInterval(5000);

SerialOutput.println("changed to slow");

}

if (strcasecmp(message,"LED FAST")==0)

{

led13.setOnInterval(100);

led13.setOffInterval(100);

SerialOutput.println("changed to fast");

}

if (strcasecmp(message,"LED ASYNC")==0)

{

led13.setOnInterval(1000);

led13.setOffInterval(200);

SerialOutput.println("changed to async");

}

}

}
Before you can build it you need to download the latest version of the lib at https://github.com/jantje/libraries/tree/master/BlinkLed

What as changed from the previous demo?

I included blinkled.h and I declared

BlinkLed led13(13,500,2000);

The 3 parameters are the led pin the on interval and the off interval. In other words the led on a arduino connected to pin 13 will be on for 500 mS and then off for 2000mS if you call led13.setup(); in setup and led13.loop(); in loop()

Adding led13.setup(); to setup about covers the changes in setup()

Now lets have a look at loop.

Loop() starts with the expected

myCommunicator.loop();
led13.loop();

Next to that I added a switch case. Unfortunately C/C++ does not support switch cases with strings so I had to implement the switch case with if statements.

The code tests for any of these strings "LED SLOW", "LED FAST" and "LED ASYNC".

If one of these lines of comments arrive I change the blinking rate of the led by stetting the on and off interval.

What is in blinkled.

Lets first take a look at the constructor.

BlinkLed::BlinkLed(uint8_t ledPin,uint32_t onInterval ,uint32_t offInterval )

{

myLedPin = ledPin; // the number of the LED pin

myLedState = LOW; // ledState used to set the LED

myPreviousMillis = millis(); // will store last time LED was updated

myOnInterval = onInterval;

myOffInterval=offInterval;

}

As you can see nothing really exiting.

Now lets look at the set on and off interval

void setOnInterval(uint32_t onInterval){myOnInterval=onInterval;};

void setOffInterval(uint32_t offInterval){myOffInterval=offInterval;};

As you can see I only set the values I do not act upon the change.

This is a very important rule for me. Only the loop() can do calculations and changes.

This approach has a lot of benefits such as:

1. If a loop takes long it can only be because of some code in the class itself.

2. The sequence of changing values is completely irrelevant. Whether you change on first and then off is of no importance as only loop will do actual changes and at that point in time both have been changed.

3. The only object that can have changed state during your loop call is the object itself. As such the loop call can consider itself as “in a stable environment”. This seriously reduces the complexity of the code. Compare it to a board game where typically each player does its move one after the other. Not having this rule makes it comparable to a multiplayer on-line game.

4. Because of these rules the re-usability of the classes has increased.

Draw backs of this approach:

Even though the loop has to accommodate for all actions it still has to be fast. Assume your loop takes 10ms to finish and you have 10 objects that means 100ms for each and every cycle in the main loop to finish. I think that is way to long. In other words: DO NOT USE DELAY() -I guess you have heard this before smiley -

And now loop()

void BlinkLed::loop()

{

// here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, if the

// difference between the current time and last time you blinked

// the LED is bigger than the interval at which you want to

// blink the LED.

uint32_t myInterval =myOnInterval;

if (myLedState == LOW)

{

myInterval =myOffInterval;

}


unsigned long currentMillis = millis();

if(currentMillis - myPreviousMillis > myInterval) {

// save the last time you blinked the LED

myPreviousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:

if (myLedState == LOW)

{

myLedState = HIGH;

}

else

{

myLedState = LOW;

}

// set the LED with the ledState of the variable:

digitalWrite(myLedPin, myLedState);

}

}

This is basically blink without delay.

Whats up next?

Now that the setup(), loop(), blinkled and serialstringreader are fully understood it is time to explain a generic way to change attributes and variables over the serial port.

Please post a comment if you want that post to be written.



  • Comments(0)//blog.baeyens.it/#post17

Controlling Arduino over the web: Blinking a led the cool way. Part 1:SerialStringReader

Arduino sketch experiancesPosted by Jan Wed, November 12, 2014 23:59:22
preface:
The loyal reader of this blog knows I have written a blog entry with a similar title before. However as I keep on using this set of libraries I also keep on improving the libraries. Therefore the old article is getting outdated on the level of practical implementation. I also recently updated all the examples using my new arduino eclipse example link feature so I guess it is time for a rewrite/reread.

Why read this article
What would you think about controlling an Arduino over the network in a easy and generic way?
In a way you only need to change the code and all processes after that are generically enough to change without having to change code?
In a way you can intervene in the intermediate steps?
In a way you automagically get a web interface that allows you to read Arduino variables, set them and save them in eeprom, in a way you fully control/understand?
Does that sound appealing?
Well than you should sit and read this and the next planned blog posts.
These posts will lead you to an example that reads out the position of 3 potmeters connected to A0,A1 and A3. Below is a browser dump of the HTML control.
It's a long road, and we'll start slow, but if you need this functionality you'd better hold on tight. On the road you'll also learn how to save setting in eeprom/yun sd card simply by setting a flag in your code.



Lets get started:
As you probably know the easiest way to communicate with an arduino is the serial port. However the serial port is a byte by byte protocol and as such needs another layer to communicate at a higher level.
People tend to work on a line by line basis. An experienced programmer can easily put a layer on the serial port to do line by line reading. As such it seems kind of crazy to make a line by line reading library. However for building on top of a line by line reader a library is needed. As it is a functionality which is requested by Arduino enthusiasts it deserves it's own library -in Arduino land-.
So lets start with the first example: a simple line by line reader to get used to the jantje's way.

#include "SerialStringReader.h"
//for the stream you want to read info from you need to declare a SerialStringReader
//you can only have one
SerialStringReader myCommunicator;

//Define that the USB serial (pin 0 and 1 on the uno) is to be used by the mySerialReader
//If you want to use the yun with the bridge use Serial1
#define THESERIAL Serial
Stream &SerialInput = THESERIAL;
Stream &SerialOutput = THESERIAL;



void setup()
{
delay(2000);
THESERIAL.begin(115200);
SerialOutput.println("serialStringReaderDemo2");
myCommunicator.setup();
}

void loop()
{
//always add the following line to your loop
myCommunicator.loop();
//mySerialReader.messageReceived() will only return true when a line of data has arrived
if (myCommunicator.messageReceived())
{
SerialOutput.println("You have send a message to Arduino.");
SerialOutput.println("And the message is:");
// with mySerialReader.getMessage() we get the actual message
// for the demo we simply play it back.
SerialOutput.println(myCommunicator.getMessage());
}
}

How to use the sketch
Download the library SerialStringReader from github https://github.com/jantje/libraries
Open the example serialCommunicatorStep1
Verify and Upload the sketch. Open the serial monitor (115200 baud) and send messages to Arduino.
Only when an end of line is send Arduino will send the info back.
That is all it does and it does it good :-D

Looking at the sketch code
The first thing I ask you to do when looking at the code is to forget the THESERIAL and SerialOutput for now. See them as simply Serial.

Working with Arduino and classes I got used to adding a setup() and loop() to all my classes. This makes that I can simply extend my existing sketches with functionality by creating a new class instance and simply call the setup and loop in setup and loop. -It probably makes more sense to read the code than reading the previous text ;-) -
This way of working will come back in all the examples here.
First I create an object called myCommunicator of type SerialStringReader.
I call the myCommunicator.setup in setup and myCommunicator.loop in loop. If later on I change the type of myCommunicator to something else there is very little to change.

myCommunicator.messageReceived() tells when a message is received and myCommunicator.getMessage() returns you the message. This is line by line.
The end of line is identified by a CR or LF or both.

Looking at the library code
If you look at the code in the library you will find that setup is blank. Here setup() only exists for compatibility reasons.
And here is the code of loop
void SerialStringReader::loop()
{
while ((!myHasMessage) && (SerialInput.available() > 0))
{
char aChar = SerialInput.read();
if ((aChar == '\n') || (aChar == '\r'))
{
myHasMessage = myMessageIndex; //this way if \n and \r are send we do not get 2 messages
myMessageIndex = 0;
} else
{
myMessage[myMessageIndex] = aChar;
myMessage[++myMessageIndex] = 0; // Keep the string NULL terminated
if (myMessageIndex >= MAX_MESSAGE_LENGTH)
{
SerialOutput.print(F("Message to long. Max: "));
SerialOutput.println(MAX_MESSAGE_LENGTH);
SerialOutput.println(myMessage);
myMessageIndex=0;
}
}
}
}

I use an array to avoid the payload of the string. The size of that array is
#define MAX_MESSAGE_LENGTH (uint8_t)80
80 may seem a bit tight but do not forget serial is a slow protocol. The longer your message the more time. Also the longer the message the more you lose program and data space. To save space I also use uint8_t so if you want messages longer that 255 you'll need to adopt the code.

Some framework explanation
Now what is this THESERIAL and serialOutput defines/variables about?
These defines and variables I use to easely swap between serial ports.
If you use the yun and want to communicate with the linux part of the yun you need Serial1. However if you connect a UNO to a PC running linux you want Serial. I have connected a MEGA to a yun and I use Serial2.
To be able to swap easily I use THESERIAl and serialInput serialOutput serialError. Like in Linux.
You can swap serial port by simply changing the #define THESERIAL to the wanted port/Stream.

Usage advice
This sample code is Arduino IDE programming level compatible. I do not advice to use the arduino eclipse plugin if you want to stay on this level.

What is next
In the next example we continue this slow pace and blink a LED. How Arduino that is :-)





  • Comments(0)//blog.baeyens.it/#post16

Linking to example ino code

eclipse pluginPosted by Jan Wed, September 24, 2014 14:41:45
In my last post I mentioned I have added support for ino files to the plugin.
Now I took it a bit further.
To avoid having to copy the code from the project to the example folder of the library I now added support for linking to the example code (Like I do by default with the libraries).
This means that wen you change the code in the created project (that link to sample code) the actual code in the library folder will be changed exactly in the same way as you change code in libraries.
This makes it easier to maintain sample code as you do not have to copy or wonder whether you have copied the code.
Off-course this is a option you do not have to use.
Here you see that the files are linked.
When the sample code contains subfolders there will be links to the subfolders.


What are the drawbacks?
Normally when you link to libraries and you change the link to the hardware or the arduino IDE the project can be fixed by re-selecting the correct options. This is due to the fact that all links are relative to a "environment variable"
The links to the sample code are hard links to the root of your storage device. So moving things around will break the links.
I do not see this as a "bad thing" because the usage scenario I support is "adopt the sample code" which is a short time based scenario.


Note that this feature is only usefull when you want to update the sample code of a library. I advice not to use this feature if you do not have a version control system controlling your library code. I also advice to check in your latest version before making a project that links to the sample code.

  • Comments(0)//blog.baeyens.it/#post15

Marvin is working ....

MarvinPosted by Jan Thu, May 29, 2014 23:48:34
... well actually not yet.
People who have been following me know that I have been working on a lawnmower robot for some years now. Marvin is his name. You know: the brains of the universe and who can do the lawn mowing?
Lately I fully redesigned Marvin and I havn't been lucky with the drive motors. As I wanted to test the mow engine I did some ducktaping and replaced the drive motors with ... a carbon based life form.
Well it is probably the biggest push mower in the neighborhood smiley

And very cool to drive:

If you want to give it a push .... that will be 10euro smiley
Best regards
Jantje

  • Comments(0)//blog.baeyens.it/#post14

Some support for ino files in the arduino eclipse plugin.

eclipse pluginPosted by Jan Wed, May 21, 2014 14:58:42
If you have upgraded to the latest version of the plugin (nightly builds only) you may have noticed that there is now some support for ino files.
I hear you say: ino files???????? I thought you didn't like those?

Well I never objected to ino files in the Arduino eclipse plugin but I never saw the need for it as well. I mean someone who can handle C/C++ should not need the functionality ino files offer. I fully support the ino file decision made by the Arduino team in the Arduino IDE, but if you step up to eclipse you should be able to do without ino file functionality. I even embraced this because this keeps the unexperienced away.
Next to that I never saw a clean way to implement ino file support.

So what has changed?
Using the Arduino eclipse plugin I learned to know some weak points that are related to ino files. These are:
1) I noticed that I still use the Arduino IDE to look at the sample programs. Each time I download a library it is simply easier to start the Arduino IDE to look at the samples.
2) The eclipse plugin is perfect to make Arduino libraries but due to lack of support for ino files there is a weak point in developing the sample programs for the library.
3) Due to the above I noticed I have lots ( read: to many for me to handle) projects in my workspace. This is cause by having sample programs for each and every library I make which I can not really delete or get rid of (as a project) due to the above. If the plugin had better support for ino files I could just drop the project in the examples folder of the library. As a result there is a clearer link between the "library and examples" and I have a cleaner workspace.
4) I found a nice way to have some support ino files.

Some support for ino files?
It are the first versions so not all functionality is there. If some functionality is to hard to implement I won't bother doing it (unless a sponsor whips out his wallet big time)
And do you have an extensive list of what Arduino IDE supports in the ino files (if so please send it to me)
What is at the time of writing the supported features:
1) joining all ino files in 1 big file.
2) inclusion of Arduino.h
3) All includes are repeated at the top af the big file (after #include "Arduino.h")
4) All function declarations are added at the top of the big file (after the includes).

And the bonus is:
For me the big advantage is that I also wrote some code to create a project based on multiple examples. In the import wizard after you have selected your Arduino you can select the examples. I opted for multiple because the granularity of a example is different from that of a real project.
While I did so I immediately also import the library containing the example. if you select 1 simple example (those who do not have library dependencies and do not depend on "special ino functionality") it should compile after the wizard has finished.


How it works?
As I sated in point 4: "I found a nice way to have some support ino files.".
I'll share that nice way so you understand what is going on in case something is not working.
First of all: the code is based on the cdt indexer and does not parse the source code like Arduino IDE does.
I query the cdt indexer and dump the info I need in a file called .ino.cpp. . files are ignored by the Arduino IDE so that makes the solution compatible.
Buy querying the CDT indexer I can do 2,3,4. After that I add a #include "xxx.ino" for each and every ino file in the project.
As a result all *.ino files are compiled as 1 big file and line numbers and references all still work.


Wait a minute... If the code of the ino file x.ino is included in .ino.cpp and x.ino the code exists 2 times; that will give conflicts.

yes and no. You have to flag *.ino (and add *.pde as well) as C++ source code in eclipse. If not, the indexer will not parse the code and the GUI will not represent the code in a nice way. These are CDT parts and they work file based so the code will exists only once for CDT.
The compilation is done by make based on a make file generated by my plugin.
So when I create the make file I exclude *.ino files from the build.


What are the currently know limitations?
1) all headers must contain #include guards
2) You can not use a define in the code before the include to modify the behavior of a header file (use the project properties to do so)

To avoid errors in the build in the generated function declaration part I need to first include the headers. As I do not want to touch your files I can not exclude the headers. therefore all headers are included 2 times.
For example the example toneKeyboard will give warnings

For the same reason as above a #define in front of your header will actually end up between the 2 includes. Due to the #include guard the second include will be ignored and as such your define is actually after the real include.

Bugs can be reported at <https://github.com/jantje/arduino-eclipse-plugin/issues>

Jantje

  • Comments(0)//blog.baeyens.it/#post13

help my robot motors are burning!!!

Arduino sketch experiancesPosted by Jan Wed, May 14, 2014 22:02:46
As the loyal reader of my posts knows by now... I am building a lawn mower robot. All of the implemented functionality is working fine; except for .... the 4WD engines.
For one reason or another these engines keep on burning. I have used quite a set of different types of engines by now, and all of them get toasted one day. And that day is ..... way to soon. From the last set I used 16 of the 20 motors. It is this set of motors in particular this post is about.

As the burning motors drives the development cost to unknown heights and it drives the development spirit to unknown lows, I have added heat sensors to the engines. the idea is to stop the robot before the motors get to hot.
The first question is what is to hot? Wikipedia comes to help
As for the motors no special rating is given I assume it is less than 90°C. Some other web page stated 70°C for standard insulation wire.
As I'm not measuring the heat of the insulation but the outside of the motor I took 50°C.
This indeed reduced the burned number of motors but it did not stop it and it increased the "cooling time" dramatically.
So I added blowers to decrease the cooling time. As I do not want blowers on the final robot I decided to increase the power of the motors. The idea is that increasing the power of the engines decreases the need for heat dissipation.
My current motors are rated 15 watt. Assuming there are on average 3 wheels touching the ground I have 45 watt available.
As to my calculations the robot should not need only 17 watt. So I start doubting my calculations and looked for a more powerful motor; preferably a brushless (as those do not loose power when running lower speeds). However the amount of 15+ watt motors on the market seems so small I can't find them.
Conclusion: Something must be wrong.

I tried to find concrete info on the influence of PWM on brushed DC engines but didn't find convincing material. So I decided to do some tests myself.
The first test I'll share with you is with the engine only loaded with the gearbox and without shielding (I mean without a metal case to keep dirt away from the motor). I used arduino prescalers 1 to 5 which means pwm frequency 31000 Hz, 4000 Hz, 490 Hz, 120 Hz and 30 Hz.
I also used my arduino eclipse plugin with the scope functionality.
The test makes one motor runs at 160 PWM. Every second the temperature is taken and plotted. This 500 times so a line is 500 seconds (or 8.333 minutes)
Channel 0 is prescaler 1 is 31000Hz. the engine was 24°C when the test started and it rose to 29°C that is an increase of 5°C.
Channel 1 is prescaler 2 is 4000Hz. the engine was 24°C when the test started and it rose to 29°C that is an increase of 5°C.
Channel 2 is prescaler 3 is 490Hz. the engine was 24°C when the test started and it rose to 32°C that is an increase of 8°C.
Channel 3 is prescaler 4 is 120Hz. the engine was 24°C when the test started and it rose to 37°C that is an increase of 13°C.
Channel 4 is prescaler 5 is 30Hz. the engine was 24°C when the test started and it rose to 44°C that is an increase of 20°C.


Even with the experimental setup I feel the conclusion is: the higher the PWM frequency the better (that is in arduino world). from 4000Hz onwards there is no improvement to be seen with the test case but there is hardly any load during the test.
The default Arduino PWM frequincy on pin 3 is 490Hz (prescaler 3). Changing to presscaler to 1 seems a good idea.

I also did the test with a metal casing around the motor to protect the engine from dirt. All other parameters are the same.

Channel 0 is prescaler 1 is 31000Hz. the engine was 25°C when the test started and it rose to 28°C that is an increase of 3°C.
Channel 1 is prescaler 2 is 4000Hz. the engine was 23°C when the test started and it rose to 28°C that is an increase of 5°C.
Channel 2 is prescaler 3 is 490Hz. the engine was 24°C when the test started and it rose to 32°C that is an increase of 8°C.
Channel 3 is prescaler 4 is 120Hz. the engine was 24°C when the test started and it rose to 36°C that is an increase of 12°C.
Channel 4 is prescaler 5 is 30Hz. the engine was 24°C when the test started and it rose to 45°C that is an increase of 21°C.


so from these tests it looks like the metal casing is not relevant. But the PWM frequency is. Due to a bug I used the prescaler 3 (with is the default). With a unloaded motor reaching 44° in 8.333 minutes I think I found the issue.

Field tests have shown the issue has been tackled.







  • Comments(3)//blog.baeyens.it/#post12

The serial monitor of the arduino connected to your yun on your local telnet

Arduino sketch experiancesPosted by Jan Thu, September 19, 2013 01:58:16
So yesterday I failed to have my arduino duemilenove connect to linino. I spend all day trying to find out what was wrong.
I'm not going to bother you with how hard it was for me to solve this and simply tell you what you need to do.
Basically the problem was that linino does not come with the usb acm driver. You can install it via the web or via the command line.

opkg install kmod-usb-acm

This works with UNO, mega, mega adk, due
But it does not work with duemilenove and I could not test the leonardo (I guess due to the dual com port issue)
While you are at it also install minicom. This is a serial monitor that allows you to connect to your arduino.

opkg install minicom

reconnect your arduino to the com port and run

ls /dev/ttyA*

you should see ttyACM0

If you see it run
minicom ttyACM0
This command will not connect you to ttyACM0 but it will use the configuration file ttyACM0. So if we configure minicom correctly the next time we run "minicom ttyACM0" it will connect to ttyACM0.
The configuration is as follows
press ctrl+A->O select port settings and then set the baut rate to the rate you usually use and the port to /dev/ttyACM0
Save the settings in the config file.
exit minicom
ctrl+A -> x -> yes
restart minicom
minicom ttyACM0
and now you have a serial connection to the arduino connected to the usb port of your yun.
If you have ssr_demo_part_2 running from one of my previous parts you see the logging flow. you can use SET to see the values you can set and everything else I explained.

But lets take it a bit further. After all you need to start putty, start minicom in putty. Why not simply working locally.
To do so load the package ser2net
modify /etc/ser2net.conf
remove all the default configurations and add
2001:telnet:0:/dev/ttyACM0:115200
Note that the last part is the baut rate of the serial monitor so I should match the number in Serial.begin(115200) of the running sketch.
run ser2net (not sure this is needed but I did ;-) )

Now start your standard telnet program on your local machine. (I use putty)
connect to your yun on port 2001 with the telnet protocol.
And you have your serial monitor :-)

  • Comments(0)//blog.baeyens.it/#post11
« PreviousNext »