HOME > > ARDUINO How To MAIN PAGE> > QDUINO MAIN PAGE     Delicious.Com Bookmark this on Delicious    StumbleUpon.Com Recommend to StumbleUpon

The library supplied with the Qduino- a battery friendly Arduino clone

Here are some unofficial notes on the Qduino's library.

This page is "browser friendly". Make your browser window as wide as you want it. The text will flow nicely for you. It is easier to read in a narrow window. With most browsers, pressing plus, minus or zero while the control key (ctrl) is held down will change the texts size. (Enlarge, reduce, restore to default, respectively.) (This is more fully explained, and there's another tip, at my Power Browsing page.)

Page contents © TK Boyd, Sheepdog Software, 9/15.

The Qduino is a very lipo friendly Arduino clone. I am setting up a number of pages about it; all accessible from my main Qduino page.

This page is a little (well, very, actually) untidy at the moment.

ROUGHLY speaking it is in several parts...

First I try to take you through one of the example programs which come with the Qduino, explain what it does, how it does it.

That program relies on some things in the library which you should have installed on your machine, along the road to getting it "Qduino ready".

The second part of the page looks briefly at how to look inside a library. It isn't hard. And what is inside some libraries are quite easy to understand... it is often worth a try. We use that to look inside the library supplied with the Qduino which supports your use of the Qduino. Libraries, among other things, "add words" to the programming language.

Then I.... don't know yet!... I hope to cover the rest of what's in the library, the stuff not covered along the way in the previous sections!



"Blow by blow" look at rgbLED and associated library matters

Well... that's the preparation done... I hope. Time to try putting a program in the Qduino and to run it.

The "rgbLED" example program supplied with the Qduino "patch" for the Arduino IDE makes a good place to start, if you want to understand what the Qduino library gives you.

Have you worked already with bespoke objects and the smart LEDs. Bits of rgbLED may seem a bit odd, if you haven't used both, but the new ideas are not rocket science. (In fact, experience with smart LEDs isn't exactly relevant... but Quin has provided routines that let you program the "User" tri-color LED almost as if it were a smart LED.)

I may have used the wrong term when I spoke of a "bespoke object".

What I mean by a "bespoke object" in rgbLED is "q".

Here, for reference while you read the rest, is a cut down (and re-arranged) version of the rgbLED program...

/* CUT DOWN "copy" of Qduino RGB LED Example...
  Original program created on 30 Jun 15 by Quin Etnyre*/

#include "Qduino.h"
#include "Wire.h"

qduino q;  // initialize the library
void setup()
    {
       q.begin();
    }

void loop()
{
  q.setRGB("red");
  delay(500);

  q.setRGB("orange");
  delay(500);

  q.rainbow(3);  // number can be 1,2,3,4 or 5

  q.ledOff();
  delay(500);

  q.setRGB(100, 150, 200);  // r, g, b values
  delay(500);

}

Early in the program, the following appears....

qduino q;  // initialize the library

That "creates" the "object" "q". An instance of the class(?) "qduino"? Whatever the formal terminology and general principles, we'll see what it is good for in a moment.

We were only able to have that line in our program because earlier we said...

#include "Qduino.h"

The stuff to create our object is inside the library Qduino.h (and associated files) that is how the IDE knows HOW to create the object, and what the object can do.

The....

#include "Wire.h"

... is a bit of a mystery. There's one inside what becomes available when you say "#include "Qduino.h"", and thus it may be a superfluous scrap from the development process. (My programs (and web-pages) certainly have enough such scraps!)

Saying "#include "Qduino.h"" gives the compiler access to Qduino.h and Qduino.cpp, which is in the same folder.

The #include "Wire.h" may be necessary somewhere to give Qduino.h things it needs... although if that is the case, I am puzzled that its "include" line doesn't have to come before the Qduino.h line... maybe that problem was avoided by the #include inside Qduino.cpp. Ah well. Ours not to reason why! (It might even, for the very simple rgbLED program be superfluous... but if it is, it won't do any harm.)

Once we have the "q" object (and we could give it a different name, if we replace "q." everywhere else)... then the following becomes possible...

q.begin();

(That command appears in the setup() subroutine.)

It, not surprisingly, I hope, "gets the q object ready for use." It initializes various things associated with the q object.

It is just like the Serial.begin(9600) you may have been using for a while. That initializes a "Serial" object. (Don't worry if this paragraph didn't reassure you... just press on...)

Now that the q object has been initialized, there are various things we can do. In this case it happens that we will do them in the loop() subroutine, with delays between the sundry "things" so we can see what they do... but we can use them anywhere, within reason.

What we learn from the example programs

Once you've done the things we've talked about already, the following are possible.

q.setRGB("red");

... would make the LED red. You can use a range of other common color names...

   red   orange   yellow
   green   cyan   blue
   purple   pink   white

Be sure to put the color name in quotes ("")

-----------

You can put the following in a program....

q.rainbow(3);

This does a sweep through some pretty colors. You always get the same sweep; the parameter determines the speed. Comment says "you can use number between 1-5"; however, from looking at qduino.cpp it appears that you can use 1, 2, 3, 4 or 5. I suspect that numbers less than 1 would be treated as a 1, and numbers above 5 would be treated as a 5.

The changing colors, during "rainbow" are much prettier when viewed reflected off of a piece of white paper. (Or through a translucent diffuser, e.g. a piece of tissue paper.)

-----------

You can put the following in a program....

q.setledOff();

It would turn the user LED off.

-----------

You can put the following in a program....

q.setRGB(100, 150, 200);

Sets the color on the "user" tri-color LED to 100 units of red, 150 of green, and 200 of blue. Those numbers can be set from 0 to 255. N.B. If all set to 255, the tri-color LED would be DARK. Set just one to 0, and the others to 255, and you have the brightest available red, blue or green.

======
I don't believe there are any handy routines for setting the color of the "STAT" tri-color LED. ("Stat" probably for "status", as in "is the cell being charged at the moment".) The "is it being charged?" question is "answered" by the green element in the tri-color LED, leaving the blue and red LEDs available for your use. There is more on the tri-color LEDs in the page which is dedicated to them.



The library files: Qduino.h, Qduino.ccp

If you know enough about programming, looking in Qduino.h and Qduino.ccp will tell you things. On my system .ccp could be accessed thus...

C:\Users\XXX\AppData\Roaming\Arduino15
   \packages\Qduino Mini\hardware\avr\1.0.6
   \Qduino\Qduino.cpp

... where XXX is my user id on the system. (Qduino.h was in the same folder) Open them with the text editor of your choice. I like Textpad.

Here are some bits of .h and .ccp. I think you can see how they inform you about "words" that the library adds to the compiler's "vocabulary"....

From Qduino.h...

class qduino
{
  public:
    void begin();
    void setRGB(int r, int g, int b);
    void setRGB(String color);
    void rainbow(int duration);
    void ledOff();
};

That, I hope, is pretty easy to follow. Note that the words (begin, setRGB, ledOff, etc) are "inside" the "thing" qduino. When we did...

qduino q;

(Along with the stuff needed to make THAT work).... we opened the door to being able to do....

q.begin();
q.setRGB("red");
q.setRGB("orange");
q.ledOff();

... etc. (The fact we used "begin" inside setup() and the rest inside loop() is not important, in some ways. The words are "created equal". It's just that WHAT THE WORD DOES makes using some in one place "right", others in a different place also "right".

Inside Qduino.h, we get an idea of what words are allowed. WHAT HAPPENS if we use a particular word is spelt out in Qduino.cpp

Take a breath. Make a cup of coffee.

Inside Qduino.cpp we have...

void qduino::begin()
{
  pinMode(13, OUTPUT);    // Blue user LED
  digitalWrite(13, HIGH);

  pinMode(11, OUTPUT);    // Green user LED
  digitalWrite(11, HIGH);

  pinMode(10, OUTPUT);    // Red user LED
  digitalWrite(10, HIGH);
}

This code will be executed when a user's program invokes "q.begin();". See how it neatly "wraps" "some stuff" in a new word, to save the user having to put in code which will appear again and again in Qduino programs?

The blue, green, and red elements of the "User" tri-color LED are on D13, D11 and D10. You can double check that against the circuit diagram, if you wish... but if you know how to look at the .h and .ccp files in a support library, sometimes you don't have to do things the hard way.


==========
Moving on to other things in Qduino.cpp....

void qduino::setRGB(int r, int g, int b)
{
  r = 255 - r;
  g = 255 - g;
  b = 255 - b;

  int newr = map(r, 0, 255, 0, 146);

  analogWrite(10, newr);
  analogWrite(11, g);
  analogWrite(13, b);
}

To skip, for the moments, bits of this, all this does is implement the setRGB command, in the form with three numbers, one for the red, one for the green, and one for the blue led light levels.

r, g and b "go in".... and very nearly "just" get passed on to the three analogWrite commands.

analogWrite(10,128); would cause pin 10 to go on/ off/ on/ off, etc, very rapidly. On about half the time (128/255 units) and Off about half the time.

The red element of the "User" tri-color LED is connected to D10 of the Qduino.

This PWM signal is how it is possible to get a dim red, a bright red, and levels in between.

Just to be complete....

The lines like "r = 255 - r;" are there because the designer wanted a big number to give you a darker LED. (The maximum valid value is 255... not, by the way, enforced by the software. Programmers will just have to know and remember... or get "odd" results. Why can't computers do what we THOUGHT they were supposed to, rather than what they were programmed to do?

The "int newr = map(r, 0, 255, 0, 146);" is there because the red LED, for the same value sent to analogWrite, would look brighter. "Map" is a basic, and useful, built-in (standard) Arduino command. With the parameters given above, it will "squash" numbers from 0-255 down to a narrower range: 0-146. A clever little bit of programming! (Even if it does "clutter the field", and make it hard, at first, to see the essential bits!)

Most of the other commands relating to the LEDs are made like the one we've just looked at in detail.

The "other" setLED, the one with just one parameter, is, for instance....

void qduino::setRGB(String color){

  int intcolor;

  if(color == "red")    { intcolor = 1; }
  if(color == "green")  { intcolor = 2; }
  if(color == "blue")   { intcolor = 3; }
  if(color == "cyan")   { intcolor = 4; }
  if(color == "pink")   { intcolor = 5; }
      ... etc.... followed by...

  switch (intcolor) {

  case 1:
    analogWrite(10, 0);
    analogWrite(11, 255);
    analogWrite(13, 255);
    break;

  case 2:
    analogWrite(10, 255);
    analogWrite(11, 0);
    analogWrite(13, 255);
    break;

  case 3:
    analogWrite(10, 255);
    analogWrite(11, 255);
    analogWrite(13, 0);
    break;

    ............. etc.

The other two example programs show you how, through software, to "look" at the state of the charge in the battery. They are written up below.


What else does the library give us?

Time for another cup of coffee.

I hope the above wasn't too difficult to follow?

In the above, I started with a little program which demonstrated some of the things available from the library. After looking at the program, I showed you the bits of .h and .ccp which allowed me to figure out bits of what was in the example program. (For instance, although I didn't show you the details, it was only by looking at the code behind "rainbow" that I was able to figure out what the number that goes with it does.)

The other good thing about looking in the .h and .ccp files is that it allows you to be sure you are missing any Good Stuff!

The "only" thing that remains in the .h and .ccp files, at least in the form I found them 25 Sep 15 is the fuelGauge class. Here's what .h gives us about that. (We may look at the example programs which demonstrate using the class later. But this time, we're going to look at the ingredients before we look at using them...

class fuelGauge
{
  public:
    int chargePercentage();
    void begin();
    void reset();
    char getVersion();
    void setThreshold(uint8_t level);
    int currentThreshold();
    bool inSleep();
    bool inAlert();
    bool verifyAlert();
    void goToSleep();
    void wakeUp();
    friend void INT6_vect(void);

  private:
    volatile static bool alerted;
    void performCommand(byte address, int value);
    void readFrom(byte address, byte &msb, byte &lsb);
};

The Big Deal (USP) of the Qduino is that it is lipo friendly. You just plug one in, and It Works.

There's a simple green LED (the one in the "Stat"us tri-color LED) to tell you, directly, in hardware, no software involved, that there is (or is not!) a lipo connected which is charging. Present, not charging? LED off. Not present: LED tends to flicker dimly. Present and fully charged: Off.

But We Want More, don't we? And Quin has set out to provide it.

Now... I'm at something of a disadvantage here, as I don't know much about lipos and their care and feeding. But! What I can tell you is that somehow, there are ways to tell... how reliably, I don't know... how often has your laptop told you that you have 2 hours of battery life left just before it dies?... but there are ways to TRY to tell how much charge a cell has.

But they involve software. And that's what the fuelGauge class ("bespoke object", I called such things earlier) is about.

There are two chips on the Qduino centrally concerned with the lipo. One is an MCP73831, and from what I've seen of the schematic, this operates without any control from, or input to, the processor. Good! That much is simple, then!

There's also a MAX17048. The Qduino schematic puts this at the heart of the Battery (Cell!) Fuel Gauge. Have a look at the MAX17048 datasheet, if you are feeling the need of some light (not) reading. (The link will launch the download of a .pdf file.)

Lots and lots and lots of talk there about all the factors which go into knowing the "state of charge" of a lipo. Interesting, if you like esoterica.

By "state of charge", I think Maxim means "what percent of the charge stored in this cell is still available?"... how long 'til it "is dead"(American)/ "goes flat"(British)

Happily, the only "interesting" pins on the chip are an output called /ALRT, which goes to an input on the microprocessor at the heart of the Qduino, and two inputs, which are both wired to the voltage the lipo is producing. From this, I infer that everything the chip "knows" about state of charge is based on the current voltage produced by the cell.

It doesn't, to me, seem likely that the chip is doing anything clever to measure how long the cell have been charged for, how long in use, etc. Whew!

The cell fuel gauge chip has two pins I recognized: SDA and SCL. They are for the I2C bus (the chip is at address 0x36). The presence of connections to the I2C bus means...

(We'll come to the complex commands and answers in a moment.)

I said "don't do things that would interfere with the I2C bus."

I believe that the lines connected to D2 and D3 have been dedicated to the I2C bus. (SDA and SCL respectively.) The circuit diagram tells me that both are pulled high with 4k7 resistors.

There is some "wiggle room" in my "don't use them" warning. If you know enough to realize that, you know enough to do only "okay" things, I hope. Novices are advised to use other pins for their wants.

-------------
Complex commands and answers:

So.. to recap: We know that SOMEHOW, the Qduino is supposed to be able to tell us things about the charge left in our cell. We've found a chip on the board with "charge left" measuring capabilities, and a way to communicate with the Qduino's processor.

The rest is just details! And Quin has given us two examples of using the fuel gauge. We'll look at each in turn.

I should confess at this point that I am "making this up as I go along". Read it very critically... there may be errors!

The FuelGauge Example

The fuelGauge example repeatedly reads the charge left in the cell from the fuel gauge chip, and then displays the charge left via the ordinary Arduino serial monitor. The data is given as a percent.

That's "all" the following program does!

(Be sure to have a cell connected if running this code. No harm will arise if one isn't present, but you'll get weird readings!)

/*  Qduino Mini built-in LiPo Battery Fuel Gauge
Edited version of Example Program fuelGauge,
which comes with the Qduino libraries, was
written by Quin Etnyre, forked from work by
Matt Newberry
*/

#include "Arduino.h"
#include "Wire.h"
#include "Qduino.h"

fuelGauge battery;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  battery.begin();

  while(!Serial);  // wait for Serial port to be opened

  Serial.println("Begin");
}

void loop()
{
  int charge = battery.chargePercentage();
  battery.reset();
  Serial.print(charge);
  Serial.println("%");
  delay(1000);
}

The code starts with three #includes. Their role is as in the previous program, rgbLED

Don't overlook the modest little....

fuelGauge battery;

.. it gives you the "battery" object, an instance of the class "fuelGauge". (This is like the "q" that was at the heart of rgbLED, in concept.)

The three "begins" in setup() make it okay to use...

1) The I2C communications between the fuel gauge chip and the processor. (That's the Wire.begin();)

2) The ordinary Arduino serial monitor

3) The Qduino library... for the fuelGauge class, and the functions and subroutines which I am about to try to explain!

After the "begins", a line to hold things up until the serial monitor is "awake", and a line to send a welcome message to the monitor to tell the user that things have started okay.

And that's all that's in setup() explained, I hope.

Now we come to the contents of the loop() subroutine....

The crucial, central command is, of course, the following...

int charge = battery.chargePercentage();

It creates a variable called "charge", and fills it with the result of a call to the function "chargePercentage()", which is provided for you by the Qduino library. You can see it in the list for the class fuelGauge, above.

Pretty simple, no? All you need to remember is....

1) Create an instance of the class. It was called "battery" in this example.

2) In setup, call the "begin();" method.

3) chargePercentage() returns an "int" type datum, so use one of those when calling the function....

4) AND ALSO REMEMBER: AFTER calling chargePercentage();, call the "reset" method.

That, in the example program, is where the line...

battery.reset();

... comes from.

After these "special" things, at the heart of what the example program is trying to show us, there are only a few odds and ends left....

We take the number we got from the fuel gauge chip and use the serial monitor to send it to the human. (Serial.print(charge);).

We start a new line on the serial monitor display (Serial.println("%");)

.... and then we impose a one second delay. Not only does this stop the new lines appearing on the serial monitor at a silly rate, but I suspect that the fuelGauge chip may need a bit of time to finish its "reset" process. (delay(1000);)

So! That, out of the words supplied by the fuelGauge class, is...

... dealt with.

(Don't confuse the limited "reset" achieved by the command above with a "full blown" reset of the whole Qduino!)

There's a note in the full version of the example saying "Check Qduino.cpp for documentation on how to put the fuel gauge to sleep and wake it up."

We'll get to that. In passing, here, I will mention that putting it to sleep may have the same benefits of putting a computer "to sleep": Reduced power consumption.

The BatteryLevelToLED Example

The previous example program helped you, I hope, to see how to use the fuelGauge class. However, the virtues of a lipo cell powered Arduino are rather badly compromised if you have to tie it to a big computer to see the state of the cell's charge!

The example program "batteryLevelToLED" simply takes the two things we've seen already, and combines them.

A reading is taken, from the fuel gauge chip, of the level of charge in the cell at the present time.

Then the "User" tri-color LED is made to light up with an appropriate color... green, yellow, orange, or red, depending on the charge level.

Oh dear. No new words dealt with. Sigh.

Other methods provided for the fuelGauge object

I always like to see a function in a library which allows programmers to learn the version of the library.

There is a getVersion() function ion fuelGauge, but I believe it returns a version identifier from within the MAX17048... a good thing to have, too. However, it would be nice if a getVersLibrary was also available, I think. (The MAX17048 is the chip at the heart of the fuel gauge provision.)

Inside the code for the fuelGauge "begin" there were once, accidentally, some lines which I would guess configure an interrupt in the ATmega32U. If you have them, don't pay too much attention to them. If you re-install your Qduino material, they will go away. (At least that was the state of things 01 Oct 15.)

The interrupt was, I think, to watch the /ALRT output of the MAX17048.

Moving on...

There is also the boolean function "inAlert()", which I presume returns true if the fuel gauge is sending (has sent?) an "alert" signal. What causes the alert? At a guess I would say it would be the fuel gauge determining that the charge remaining has fallen below a certain percent. What clears it? Perhaps it clears itself, as soon as the charge rises above the "certain percent"?

And then there's "currentThreshold()". At a guess: This tells you the level of charge which would make the fuel gauge chip send an alert... which, I think, is a case of it making it's /ALRT line low.

Continuing this self-consistent, though entirely un-confirmed analysis, there's "setThreshold(uint8_t level);". This, in my possibly alternative universe, sets the level at which alerts are set/cleared. (Prizes... well, my high esteem, anyway, to anyone who can identify the reference to "alternative universe".)

There's also a "verifyAlert()" subroutine. I'm not sure how this is different from the "inAlert()" function. You are stuck(?) with providing a test of inAlert() "by hand" from time to time, i.e. polling it,... so why the need for a second way to see if an alert is in effect?

And that covers the family of "alert" functions and methods.

Remaining elements of the fuelGauge class

The fuelGauge class has the following...

    bool inSleep();
    void goToSleep();
    void wakeUp();

Have you met the idea of a chip "sleeping"?

Chips that can "sleep" will enter an alternate state. In that state they use little power... good, in a battery powered device, don't you think?

But, as ever, nothing's for nothing. When the chip is sleeping, it can't perform the functions it otherwise can. But I see no reason you'd want to continually monitor the state of your lipo. A check every half hour should do, don't you think? And, if all my guesses are close enough to the truth, the fuel gauge chip doesn't need to monitor the current flow continuously. (I don't see anything in the circuits which would make it possible for it to do so. This is part of the reason I suspect it infers remaining charge simply from the precise voltage of the lipo at the moment. It would seem that lipos have very low internal resistances. But that would fit with the dangers of short circuits.)

Given the first part of the previous paragraph, I suspect you can make the same guesses I have about the purpose and use of the three bits of the class listed before it.

Last last bits....

That leaves just...

friend void INT6_vect(void);

... from the public part of the library.

There are a few things in the private part, but I believe that the point of a private part is that you aren't supposed to use the things there!

Oops... one other thing...

We've finished with the full tour of the functions and subroutines provided in the Qduino libraries.

There are also a bunch of things there like....

#define MAX1704_POWER_ON_RESET  0x54

.... which allows you, in writing code, to use MAX1704_POWER_ON_RESET anywhere you would otherwise write 0x54.

0x54 is the code to send to the Max1704 if you want it to do a power on reset. The presence of the "#define" allows you a more easily remembered way of referring to the command.

Mischief Managed?

I hope that answers questions you had? Including "is there anything else the library provides for me?

Do please get in touch (see below) if not. Or even just to say "thank you". Mentions of this page in forums, Facebook "likes", etc. always appreciated... and will encourage me to more like this, and bring word of it to others who might find it useful?



To search THIS site.... (Go to my other sites, below, and use their search buttons if you want to search them.)
Click this to search this site without using forms.

powered by FreeFind
Site search Web search

The search engine merely looks for the words you type, so....
*    Spell them properly.
*    Don't bother with "How do I get rich?" That will merely return pages with "how", "do", "I"....

Please also note that I have two other sites, and that this search will not include them. They have their own search buttons.
My site at Arunet.
My Sheepdog Software pages, another of this page's editor's sites.


Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.




Here is how you can contact this page's editor. This page, and the software it references, ©TK Boyd, 8/2015.

Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org