SunRover Part 4 – Adding a Pi Camera and Diagnostics System

Camera Pan and Tilt

The pan-and-tilt mechanism [8] for the camera is the same as the one I used in MouseAir [9], because it comes with the motors and mounting hardware (Figure 4), although the next time I do this I will probably 3D print a pan-and-tilt mechanism [10].

Figure 4: Pan-and-tilt hardware.

For the two servo motor controls, I used the Adafruit I2C 16-channel servo kit (Figure 5), even though I knew I wouldn't be using 16 servos [11], because I already had one in my bench drawer. The pan-and-tilt kit uses one servo for rotating in the xy plane and one for rotating in the zx plane. Although the geometry is a little complex, the code is pretty simple.

Figure 5: Adafruit I2C 16-servo motor controller (center) installed.

In Listing 2, I have two servo routines (lines 1-8 and 7-19) that set the pan and tilt in degrees, with the plane of the robot set at 0 degrees and with 90 degrees straight up in the z direction. These values were measured empirically by turning the servos, figuring out what value gave what number of degrees in the full on/off position, and then setting the constants so the input values make sense to the programmer.

Listing 2

Pan/Tilt Camera Control

01 def setTiltServo(pwm,degrees):
02     servoMin = 150  # Min pulse length out of 4096
03     servoMax = 600  # Max pulse length out of 4096
04
05     degrees = -degrees+90
06     servoPerDegree= (servoMax - servoMin)/180.0
07     if ((degrees > -45) and (degrees < 135)):
08         pwm.setPWM(1,0, int((degrees+45)*servoPerDegree+servoMin))
09
10
11 def setPanServo(pwm,degrees):
12     servoMin = 150  # Min pulse length out of 4096
13     servoMax = 600  # Max pulse length out of 4096
14
15     servoPerDegree= (servoMax - servoMin)/270.0
16     degrees = -degrees
17     if ((degrees > -135) and (degrees < 135)):
18         value = ((degrees+135)*servoPerDegree+servoMin)
19         pwm.setPWM(0,0, int(value))
20
21
22 def shutOffPanTilt(pwm):
23     pwm.softwareReset()
24
25
26 # Camera stuff
27
28 def takeSinglePicture(camera, pwm, pan, tilt, name, i2CMux, bus):
29
30
31     i2CMux.write_control_register(bus)
32
33     setTiltServo(pwm, tilt)
34     setPanServo(pwm, pan)
35     camera = picamera.PiCamera()
36     time.sleep(2)
37     camera.rotation = 180
38     camera.annotate_background = picamera.Color("black")
39     camera.resolution = (1024, 768)
40     camera.annotate_text_size = 24
41     heading = ABWCommands.execute_command(ABWCommands.RCOMP,"")
42     if (heading == ""):
43         heading = 0.0
44     else:
45         heading = float(heading)
46
47     camera.annotate_text = (
         " SunRover p:%d t:%d heading:%4.1f ") %
         (pan, tilt, heading) +
         datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
48
49     camera.capture(name)
50     camera.close()
51
52     shutOffPanTilt(pwm)

The camera still-picture routine (lines 28-51) closes the camera on each picture (line 49). If I want a series of pictures, I will write another routine.

As the camera moves and takes a picture, it seems a little anthropomorphic (actually, a little creepy) seeing it look around with the motors whirring. The unfinished RasPiConnect [12] control panel for the camera is shown in Figure 6.

Figure 6: Camera control panel.

Three additional features are planned for the camera system:

  1. Time-lapse photography. This will be especially cool when SunRover is moving or tracking the sun.
  2. Streaming movies. The camera can do it, the picamera software can do it, and RasPiConnect can do it. It burns a lot of power, but it will have to be done.
  3. Motion detection. A lot of software is available for the Raspberry Pi for motion detection, although it will require quite a bit of work; moreover, I have the power to consider.

I2C Diagnostic System

SunRover is complex: The power systems run, and the solar cells collect power. Thirty I2C devices and sensors are installed, most of which are connected with their respective drivers (e.g., the lightning detector [13] and WeatherArduino [14], although the anemometer/wind vane/wind speed system is not hooked up yet). The motors are working well since I fixed the equipment bay grounding and power distribution system, so the rover can turn pretty well and take pictures.

The RasPiConnect control panels are now coming together. Figure 7 shows a summary of the SunRover command panels, of which three are mostly working. The diagnostics reporting system is working, and the other data will be added over the next couple of weeks. The Arduino power management system is gathering the data and sending it to the Raspberry Pi 2 for processing.

Figure 7: SunRover block diagram.

With all of different subsystems in SunRover, I have tried to build in a lot of options and redundant systems (e.g., the solar power panel multiplexer [2]), so the robot can still function when things going haywire. I have done this in a lot of other projects (e.g., Project Curaçao), and it pays off. In the case of SunRover, I wanted a single set of functions that will go through all of the subsystems and, to the best of its ability, test for presence and functionality. Figure 8 and Listing 3 are examples of the results of the first section of this code, which checks the health of the I2C bus and tests for the presence of sensors. More tests are planned for the SunRover robot, such as motor and compass functionality testing. Because the compass is a critical piece of the navigation system, I am putting a second compass in SunRover.

Listing 3

Diagnostic Report

Totals Present:   Present:30 Missing:1 Extra:1
Diagnosis Report: Arduino
Generated at:2016-02-06 21:25:25
Present: 23 Missing: 0 Extra: 0
Bus: 0
Device Present address: 0x1e | Compass|HMC5883L Compass
Device Present address: 0x21 | QPM0|Quad Power Management Board 0 - LS0/TRex LS1/Fan0 LS2/Fan1
Device Present address: 0x3c | OLED-01|OLED Display for Arduino
Device Present address: 0x40 | SAP0-INA3221|Motor Battery SunAirPlus Voltage Current Sensor
Device Present address: 0x48 | SAP0-ADS1015|Motor Battery SunAirPlus ADC
Device Present address: 0x73 | I2CMux1|Arduino 4 Channel I2C Mux
Device Present address: 0x5c | AM2315_0|Inside Temperature and Humidity
Bus: 2
Device Present address: 0x20 | QPM3|Quad Power Management Board 3 for Solar Multiplexer
Device Present address: 0x21 | QPM2|Quad Power Management Board 2 for Solar Multiplexer
Device Present address: 0x40 | SAP1-INA3221|Raspberry Pi2 SunAirPlus Voltage Current Sensor
Device Present address: 0x48 | SAP1-ADS1015|Raspberry Pi2 SunAirPlus ADC
Device Present address: 0x73 | I2CMux1|Arduino 4 Channel I2C Mux
Bus: 3
Device Present address: 0x21 | QPM4|Quad Power Management Board 4 for Solar Multiplexer
Device Present address: 0x40 | SAP2-INA3221|Arduino SunAirPlus Voltage Current Sensor
Device Present address: 0x48 | SAP2-ADS1015|Arduino SunAirPlus ADC
Device Present address: 0x49 | WPA-ADS1015|WeatherPiArduino ADS1015 ADC
Device Present address: 0x50 | WPA-FRAM|WeatherPiArduino Logging FRAM
Device Present address: 0x57 | WPA-EEPROM|WeatherPiArduino EEPROM on RTC Board
Device Present address: 0x68 | WPA-DS3231|WeatherPiArduino Real Time Clock
Device Present address: 0x73 | I2CMux1|Arduino 4 Channel I2C Mux
Device Present address: 0x77 | WPA-BMP180|WeatherPiArduino Barometer/Temperature Sensor
Device Present address: 0x7c | UNKNOWN
Device Present address: 0x5c | AM2315_1|Outside Temperature and Humidity
Diagnosis Report: Raspberry Pi2
Generated at:2016-02-06 21:25:26
Present: 7 Missing: 1 Extra: 1
Bus: 0
Device Present address: 0x21 | QPM5|Quad Power Management Board 5 for Bright LEDS
Extra Device address: 0x48 | UNKNOWN
Device Present address: 0x50 | SERVO|16 Servo Control Board
Device Present address: 0x70 | ALLSERVO|All 16 Servo Board Write Address
Device Present address: 0x73 | I2CMux0|Raspberry Pi2 4 Channel I2C Mux
Device Missing address: 0x49 | UNKNOWN
Bus: 1
Device Present address: 0x73 | I2CMux0|Raspberry Pi2 4 Channel I2C Mux
Bus: 2
Device Present address: 0x73 | I2CMux0|Raspberry Pi2 4 Channel I2C Mux
Bus: 3
Device Present address: 0x73 | I2CMux0|Raspberry Pi2 4 Channel I2C Mux
Figure 8: Testing for presence and functionality of components.

The diagnostic report, fresh off the robot, shows 30 I2C devices, identifies them, and indicates that one is missing and one is not expected (extra). The one missing and one extra are just faults induced for testing. Actually, no problems were reported at all – currently. This changes sometimes! I am having a problem with the SAP1 I2C Grove plug, and it shows up as bad sometimes, so I need to replace that cable.

The I2C diagnostic report is run in two parts. The first part is run on the Arduino power manager and the second part is run on the Raspberry Pi. A total of eight I2C buses are scanned and checked against a configuration table to see what is missing, extra, and unknown.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content