Beginner with embedded development

Firmware/software/electronics/mechanics
Post Reply
Call_me_a_Cab
Member
Posts: 51
Joined: Wed Dec 17, 2014 12:56 pm

Beginner with embedded development

Post by Call_me_a_Cab »

Hi guys,

This is my very first post on any forum anywhere so please be gentle with me...

Please excuse the obvious noob questions but,

I'm used to industrial control logic and I thought I would have a look into embedded and have bought a crazyflie 2.0. In the VM when I open eclipse and browse to the crazyflie firmware, I'm so baffled that I don't even know which language the code is written in :(

From reading the forums, I get the impression that i'm not alone in this and my hope is that others can read this post and have a "light bulb" moment where things click into place a little bit.

I'll talk briefly about a (PLC ladder logic) control situation from work today and then how that relates to my questions and my presumed knowledge of how embedded might work:

So we had this problem where a pneumatic cylinder was pushing a roller against another roller at a certain point during a machine sequence and that was causing some of the product running between the two rollers to break. What we wanted to achieve was that the cylinder wouldn't operate until both rollers were stationary. The first thing we tried was to add an inverse contact saying that when the PLC output is allowing the Drive to run, Don't allow the cylinder to operate. This failed because although the drive was no longer "running" it was still decelerating so as soon as the contact dropped out for the drive the cylinder closed and the product broke.

After a little bit of research I found the the drive has a terminal that will output 24V whenever it is at "Zero Speed", we fed this 24V into a spare input on the PLC and wrote a line of code saying that the cylinder output may only come on when the "zero speed" input is on, and that was that! :)

I suppose what my question really is and what I hope others will benefit from is...

Am I totally misguided in thinking that on the Crazyflie, the code is saying to the controller "when input 0.00 gives a certain reading turn on output 10.00 to control an LED (or whatever)" and "if Input 01.04 is off but 01.05 is on then turn on bit 07 in register number 3 (or whatever)"

If that is the case (and I really hope I've not been THAT naive) then where in the firmware would I start to look for that kind of code and (sorry about this one) which language would it be written in. :)

P.S. I see various suffixes for the firmware files and wonder if for example .c means c++ code? I think I've seen: .c .h and .o

Thanks in advance for hopefully not castrating me for my ignorance
whoenig
Expert
Posts: 395
Joined: Mon Oct 27, 2014 2:55 am

Re: Beginner with embedded development

Post by whoenig »

The firmware itself is C-code (not C++ which would add something called object oriented programming). The PC-side is written in Python.

Your assumption about about "if a do b" is correct. However, the control algorithms used to ensure a stable flight are far more complex than simple if-then-else statements. That's probably why you are overwhelmed if you look at the firmware. The easiest might be to start with getting an LED to blink or a single motor to spin.
Call_me_a_Cab
Member
Posts: 51
Joined: Wed Dec 17, 2014 12:56 pm

Re: Beginner with embedded development

Post by Call_me_a_Cab »

Thanks! At least it's similar to what I know and I can stop doubting myself now :)

Could you please help by pointing me in the general direction of the c file that contains the code for setting the expansion pins...

My plan for learning is as you suggested - start really simple. I would like to pulse an led through the prototype board, stuff like that.

A sort of Mid term goal is to have the LEDs on the exp ring change from green to red progressively as the battery looses charge - a bit like a clock.

Thanks
whoenig
Expert
Posts: 395
Joined: Mon Oct 27, 2014 2:55 am

Re: Beginner with embedded development

Post by whoenig »

I think the best start might be to make sure that you can compile and flash the firmware. If you want to go with the neopixel-ring, you can find the relevant code here: https://github.com/bitcraze/crazyflie-f ... ixelring.c. neopixelringWorker() is called periodically and you can change the LEDs by updating the buffer variable (R-G-B values for each LED) and calling ws2812send().
Let us know how it goes! The CF is definitely a great platform to learn embedded systems.
chad
Expert
Posts: 555
Joined: Sun Sep 28, 2014 12:54 am
Location: New York, USA
Contact:

Re: Beginner with embedded development

Post by chad »

Crazyflier - my CF journal...
4x Crazyflie Nano (1.0) 10-DOF + NeoPixel Ring mod.
3x Crazyflie 2.0 + Qi Charger and LED Decks.
Raspberry Pi Ground Control.
Mac OS X Dev Environment.
Walkera Devo7e, ESky ET6I, PS3 and iOS Controllers.
Call_me_a_Cab
Member
Posts: 51
Joined: Wed Dec 17, 2014 12:56 pm

Re: Beginner with embedded development

Post by Call_me_a_Cab »

Wow Thanks for the help guys, I'm slowly starting to get a handle now...

I have a crazyflie 2.0 with the led ring exp board, I read on the wiki that drivers exist in the firmware. I only found drivers for the neopixle ring so far (thanks to whoenig!!) Is it the same for the adafruit ring and the new led board?

At the min im still confused about how an instruction such as neopixelringWorker() is inturpreted by the c language - IE how does the code know what to do with a (presumably) non standard instruction such as this... I'm going to have a read of the book "the c programming language" that I found through reading this post https://cfusting.wordpress.com/2013/07/ ... tric-data/

I'm thinking that #define might be the key to define a function block such as above. Chad's blog is definitely helping too!!

Thanks again and I hope other beginners can read this and have a "mental click" too!
dbrgn
Member
Posts: 51
Joined: Tue Dec 16, 2014 9:42 pm

Re: Beginner with embedded development

Post by dbrgn »

Call_me_a_Cab wrote:A sort of Mid term goal is to have the LEDs on the exp ring change from green to red progressively as the battery looses charge - a bit like a clock
!
Hey. That battery charge indicator is actually a *really* great idea. I just did my first firmware hack and implemented that (although I used blue instead of green).

Spoiler alert: Here's the diff. https://gist.github.com/dbrgn/35d4b4c01650485bf02c Ignore it if you want to try yourself.

You can find the file that needs to be adjusted in `modules/src/neopixelring.c`. To simply get these changes to run:

1. Apply changes from diff
2. Type "make"
3. Turn your crazyflie off, disconnect the battery. Then push the button. Plug the USB in while still holding the button. The blue LED will first blink slowly, then quickly. When it blinks quickly, release the button. The Crazyflie is now in DFU mode for firmware flashing.
4. Type "make flash_dfu".
5. When it shows "download done" everything is fine. Disconnect USB, reconnect battery, turn it on. The effect should work right away.

Some hints on how it works:

- To create a new effect, you need to add a new function with the signature `static void yourEffect(uint8_t buffer[][3], bool reset)`. The buffer param is actually an array, where the first index is the LED number (0-11) and the second index is the color (red, green, blue). Color values are from 0 (off) to 255 (on).
- To register the effect, add it to the `effectsFct` array.
- To use the effect, you need to set the `ring.effect` parameter to the number of your effect in the array (0 index based). You can set the default by changing the `effect` variable in the file. Or you can set the parameter via cfclient (add the "Parameters" tab in the "View" menu then click on a value to change it).
- The effect function will be called over and over again by the crazyflie firmware.
- The effect uses the logging system to retrieve the battery voltage. If you enable the "Log TOC" tab in cfclient you can see all possible log values. I used `pm.vbat`. With the "Plotter" tab you can actually view the values.
- The `logGetVarId` function retireves the ID of that log value. The `logGetFloat` function retrieves the logs from that ID as an actual float value.
- The lower and upper bounds of the battery can be set using the custom `ring.emptyCharge` and `ring.fullCharge` parameters. The default is set to 3.1 and 4.2, see http://www.rchelicopterfun.com/rc-lipo-batteries.html for more information about LiPo batteries.
- The LIMIT macro clamps values to the range 0-255 (so -5 becomes 0 and 280 becomes 255).
- The LINSCALE macro linearly scales/translates a value in range [a-b] to range [c-d]. In our case we want to scale the voltages of 3.1-4.2 to blue values of 0-255 and red values of 255-0.

I think that's it. I hope everything I wrote is correct, as I got most things from reading sourcecode and simply guessing. I'm not an experienced C programmer :) I could also do a blogpost on it, and if the bitcraze guys are interested, a pull request. I find this effect very useful.

@Call_me_a_Cab: If that overwhelms you, start reading books about C programming. I can recommend books by O'Reilly: http://shop.oreilly.com/category/browse ... mming/c.do If you want to learn more about microcontroller programming, by all means, get this book: http://shop.oreilly.com/product/0636920028161.do I started doing microcontroller coding with this book myself, it's one of the best tech books I've ever read :)

Hope that helps :) And if you don't understand something, never be afraid to ask.
Call_me_a_Cab
Member
Posts: 51
Joined: Wed Dec 17, 2014 12:56 pm

Re: Beginner with embedded development

Post by Call_me_a_Cab »

@dbrgn thanks, what a great explanation of your code. I kind of get the gist but the value ranges confuse me somewhat still, I need to sit down with some coffee and get my head around those.

As soon as Christmas morning comes and I can finally open my Flie ;) I'll load you firmware and check it out in action.

A tip for any other beginners out there is that I've gotten "newbieIDE" for windows and have been going through the earlier mentioned book to learn the basics of C. I found Eclipse in the VM a bit daunting to be honest and newbieIDE is quite simple in comparison. I'm sure when I get some understanding under my belt, Eclipse (and the VM in general) will be great though.

One thing I'm still not seeing clearly is any code which actually says to the controller " ok, those conditions are true so turn on a physical output". The book suggested by dbrgn looks like it may help a lot with that.

Cheers!
dbrgn
Member
Posts: 51
Joined: Tue Dec 16, 2014 9:42 pm

Re: Beginner with embedded development

Post by dbrgn »

Call_me_a_Cab wrote:A tip for any other beginners out there is that I've gotten "newbieIDE" for windows and have been going through the earlier mentioned book to learn the basics of C. I found Eclipse in the VM a bit daunting to be honest and newbieIDE is quite simple in comparison. I'm sure when I get some understanding under my belt, Eclipse (and the VM in general) will be great though.
I don't like Eclipse much either :) The most important thing is syntax highlighting. Code completion is nice, but not really necessary.
One thing I'm still not seeing clearly is any code which actually says to the controller " ok, those conditions are true so turn on a physical output". The book suggested by dbrgn looks like it may help a lot with that.
If you look in the README file inside the firmware repo, you'll see a quick overview of the file structure.

For the hardware control, I think you need to take a look at the drivers directory. For example in `drivers/src/motors_f405.c` you can find the motors driver.

If you look at the DEFINEs, you can see that aliases are set for register variables. These register variables look like normal variables, but are actually hardware registers that affect how the hardware behaves. Example:

Code: Select all

#define MOTORS_TIM_M1_PERIF       RCC_APB1Periph_TIM2
#define MOTORS_TIM_M1             TIM2
#define MOTORS_TIM_M1_DBG         DBGMCU_TIM2_STOP
#define M1_TIM_SETCOMPARE         TIM_SetCompare2
#define M1_TIM_GETCAPTURE         TIM_GetCapture2
If I'm not mistaken these variables come from the `stm32fxxx.h` header file. If you want to learn more about these hardware registers, I'd suggest the "http://shop.oreilly.com/product/0636920028161.do" book again that I mentioned in my last post.
Post Reply