Quick demo video and current status

I just figured out that I always show my work in progress, but I never show the car when it is working. So here it is, a small video showing the car as its current status.

I totally rewrote the iOS application. I wanted to make some big changes with the software architecture, and I decided it was a good opportunity for me to learn deeply the Swift language. So I rewrote everything from Objective-C to Swift.

And for those who don’t want to read my previous post and want to know what I am talking about : I took a RC car, removed the radio part on the car, and replaced it by my own hardware. This now allows me to pilote the car with an iPhone or an iPad, and with a video feedback from the camera I installed on the car. And here is how it works :

  • a standard RC car I bought (not too cheap, it has to have standard components and connexions, like a standard servo motor and brushless motor). I removed the radio part and controls now directly the brushless motor and the servo motor for the direction.
  • a Raspberry Pi B+, running with Arch Linux OS, which is lighter than the Raspbian installed by default on a RPi.
  • on the top of the Raspberry Pi B+, a daughter board I conceived and made manufactured. On this board, there is :
    • power management : it take the 12V from the battery, makes +5V and +3,3V for the RPi, the servo power, and the PIC. It is done with a PWM power controller so there isn’t too much power loss from the battery, and not too much heat dissipation needed.
    • dsPIC33 : a 16 bits dsPIC which manages :
      • the control of the servo and the motor; it generated the 1ms to 2 ms pulse required
      • PID control of the motor: there is a sensor coming back from the motor to the PIC for that, but it is not yet implemented in software.
      • power monitoring : there is a divisor bridge on the +12V coming from the battery, and going to an ADC of the PIC so the battery level is monitored. This currently works but I am still calibrating it.
      • status leds : the PIC just blinks the status leds
    • Status leds :
      • 1 indicating if the hardware is powered
      • 1 indicating if the PIC is running
      • 1 indicating if the RPi is running and communicating with the PIC
  • A camera on the top of the car; it is the standard camera sold for the Raspberry Pi. The video streaming is made with GStreamer, it is an open source library made for video streaming. It is quite light, it has been ported on almost all possible OS (including Arch Linux and iOS for my needs); and most important it can achieve streaming with a very low latency.
  • a headlight at the front of the car. It is composed by a small PCB with 8 white leds. And it is here not only for fun, but when it test the car in low light conditions, it is very useful !
  • An iOS device. My Application works on both iPhone or iPad. Currenlty the application has the following features :
    • display the video streaming coming from the car, with a very low latency
    • allow to control the motor and the direction of the car. There is also a manual break, and a command to change the lights on the car, or even flash the headlights.
    • modify the motor cartography, this allows me to decrease the maximum speed of the car (which is too much powerful, especially when used inside), and to give a little more power when the starting the car. But for sure the possibilities are endless, the cartography is fully configurable.
  • A bluetooth gamepad, made for iOS, it is optional, but it is much more easy to control the car with rather than with the iOS device itself. I won such a device several month ago; it is a Mad Catz C.T.R.L.i gamepad, and it works great.

I thinks that’s it for now. So the only thing in the list above which does not work yet is the PID controller for the motor, everything else works. I also have to mention that each system (the Raspberry Pi, the iOS application and the PIC) has its own failure management, each of them is able to detect if it is still communicating with the other parts, and if there is a problem of communication, the car is stopped, and the servo and the motor are put in an idle position. The iOS application and the Linux software react in 1 second, and the PIC reacts in 200ms.

Sorry for the long post, and I don’t have any potato. Next step : the PID controller, stay in touch.

RPi datasheet errata for SPI AUX

As I previously mentioned, for my car, I am using the auxilary SPI1 module, and not the SPI0 peripheral which is used by many, and which is the only one implemented in the Linux drivers (or even by WiringPi). So I had to implement my own driver to be able to communicate with the dsPIC on my daughter board.

The problem I faced, and I already mentioned it in a previous post, is that the datasheet provided by broadcom has a lot of errors and “unclear” behaviors. I will try to detail all the problems I had faced.

There already is an errata page on eLinux.org, but until I can figure out how I can edit the page or tell them what I found, it will at least be here.


Errata

  • p24 : AUXSPI0/1_CNTL1 Register table, the bit numbering is wrong, it should be 31:11
  • p25 : AUXSPI0/1_STAT Register table, this one is important, it caused me a lot of troubles.
    • 31:28 : TX FIFO Level (note that the maximum value is 4, so not all the 4 bits are needed)
    • 23:20 : RX FIFO Level (same remark as above)
    • 10 : TX full
    • 9 : TX empty
    • 8 : RX full
    • 7 : RX empty
    • 6 : busy
    • 5:0 : no change, but not very usefull

Here is how I found it (after several guess and tries) : After boot and after starting the peripheral, the value of the STAT register is 0x00000280, which is only 2 bits high, so we can guess they are the empty status bits. Then, in a while loop, I write values in the IO buffer and I read the STAT register each time. After 4 loops, the TX buffer is full, and we read the value 0x40400540; so we still have 2 bits high in the lowest bytes, they must indicates a full status, because when we send frames, it is a SPI bus, so we receive at the same time, event if there is nothing really send on the other side, so we have a TX full and RX full bits high; and we can see on the highest bytes that we have two ‘4’ values, which is the size of the FIFOs, so this is just the TX and RX FIFO levels, as indicated in the datasheet, but with a different placement.

  • p26 : PEEK register address is 0x7E21508C, but indicated 0x7e215094 on page 8; 0x7E21508C value is the correct one.
  • p26 : IO register address is 0x7E2150A0, but indicated 0x7e215090 on page 8; 0x7E2150A0 value is the correct one.
  • p26 : PEEK and IO registers show a width of only 16 bits of data, but the datasheet mentions that it is a 32 bits SPI peripheral, so I think this is wrong (I only use it in 16 bits mode, so I didn’t have the problem)

 


Undocumented behavior

I think I also mentioned that in another post, but I had a problem when using the SPI in 16 bits mode. You can choose the bit length which is shifted out by settings bits 5 to 0 of CNTL0 register. You think this is it, and it’s working… no it would be too easy; because there also is a very strange behavior of this SPI peripheral : by default, it shifts out (in MASTER mode) the LSB first ! This is (at least I think) absolutely not conventional for a SPI peripheral. Fortunately for us you can change this, and set the bit 6 of CNTL0 register, and here we go … oh no, it doesn’t work …

What is happening here, you configured a length of 16 bits to shift out, and you tell the SPI peripheral to shift MSB first, so it does exactly what you asked, it shifts out the 16 highest bits of the IO register … which is a 32 bits register ! So the only thing we have to do to fix this, is to write in the 16 MSB of the IO register, and then our 16 bits wide data will be shifted MSB first out of the SPI master. (It took me some time to figure this out, so I hope it can help someone else).

 

I did not test each feature or each configuration of the peripheral, only the use case I needed, so there might be some other problems, but at least for a basic usage, I think this errata will help.

Stay in touch, I will post soon some news about the progress on my remote car project.

 

 

Integration in progress

I am currently finishing the software of the dsPIC for my new hardware.
I am integrating the features progressively, and it is almost done. I can (eventually again) control the motor and the steering of the car.

The longest part was to develop the SPI drivers on both the Raspberry Pi and the PIC. I chose to used the 2nd SPI peripheral of the RPi, which is part of the auxiliary peripherals (called universal SPI master in the datasheet), and does not work at all like the main SPI controller (which of course I did not check before…). And as usual the documentation of the RPi was not very precise. The most weird problem I faced is that the RPi SPI outputs the LSB of the data first by default, which is very unusual for a SPI bus. There is a parameter to output MSB 1st, but when you choose it, it outputs the MSB of the 32 bits buffer register, and I had configured to output a 16 bit value, so all I had was some zeros on the bus. It took me some time to understand the trick.

As you can see on the pictures, I also added a light on the front of the car, and this is not just for fun, I often perform my tests when it is dark outside, and I cannot see anything on the camera if there isn’t some good light.

I still have to finish and calibrate the software which measure the battery level, and I have to develop the PID controller for the motor, I did not start this part at all.