#EV3Basic Using the Mindsensors Heat Sensor and Charmed Labs PixyCam with EV3 Basic

Continuing my series about robotics and using non Lego devices with EV3 Basic, here is an article which demonstrates how to use a camera and heat sensor.
The Robocup Junior Australia competition has introduced a new Rescue division this year (2017) for a Maze rescue. The Maze rescue challenge is much closer to a real life example of a how a rescue robot can save lives.
Maze rescue does not involve any line following, as real buildings don’t have lines on the ground marking paths to follow. The robot must navigate a building, represented by a maze, by identifying walls and working its way around the maze. It needs to explore every corridor and room to locate victims wearing Hi-Vis vests (represented by bright colours on the walls) and identify whether a victim is alive or dead (by looking for a heat source).
This seventh article covers using the Mindsensors IR Temperature Sensor for EV3 or NXT and Charmed Labs PixyCam (CMUcam5) for Lego with the EV3 Basic extensions for Microsoft Small Basic.
The Mindsensors IR Temperature Sensor for EV3 or NXT is a Lego Mindstorms compatible device that can read ambient temperature as well as a target temperature of an object it is pointed at.
The Charmed Labs PixyCam (CMUcam5) for Lego is an updated variant of the PixyCam (Firmware version R1.3A) that is directly compatible with Lego Mindstorms using an appropriate cable.
Note: Mindsensors recently released an updated NXTCam5, which could also be used. It has an I2C interface and so could be used from EV3 Basic.
Mindsensors provide the drivers (blocks) and samples to use the Heat Sensor with EV3-G and some other languages (RobotC), but do not have anything to show how it works with EV3 Basic. Using the I2C interface I have retrieved the ambient and target temperatures in degrees Celsius.
Charmed Labs provide a block for EV3-G but again, there is nothing to show how it works with EV3 Basic other than the documentation for the I2C interface. Using this interface I have retrieved the number of objects and the position and size of the largest object for the first two colour signatures.
Using these two devices will allow a Maze rescue robot to see a victim and detect if the victim is alive (target temperature higher than ambient temperature). Below is a example program; it is expecting the PixyCam to be connected to port 2 of the controller brick and the Heat Sensor to be connected to port 3.
EV3 Basic
' ** PixyCam & IR Test **
' By David Musgrave
' http://WinthropDC.com
' Last Modified: 16-Jun-2017
' ** Setup Starts Here *******************************************************************************************************
' Initialise Variables
Finished = "False"
Clicks = ""
' PixyCam for Lego
I2CCamPort = 2
I2CCamAddr = 1 ' 0x01 I2C Address
I2CCamReg = 0
I2CCamWriteByte = 0
I2CCamWriteData = Vector.Init(1, 0)
I2CCamReadByte = 0
I2CCamReadData = Vector.Init(5, 0)
CamSignatureMax = 2
CamSignature = 0
For CamSignature = 1 To CamSignatureMax
CamCount[CamSignature] = 0
CamPosX[CamSignature] = 0
CamPosY[CamSignature] = 0
CamSizeX[CamSignature] = 0
CamSizeY[CamSignature] = 0
EndFor
' Mindsensors.com IR Sensor
I2CIRPort = 3
I2CIRAddr = 21 ' 0x2A I2C Address / 2
I2CIRReg = 0
I2CIRWriteByte = 0
I2CIRWriteData = Vector.Init(1, 0)
I2CIRReadByte = 0
I2CIRReadData = Vector.Init(4, 0)
IRAmbient = 0
IRTarget = 0
' ** Subroutines Starts Here *******************************************************************************************************
Sub ReadCamera
For CamSignature = 1 To CamSignatureMax
I2CCamReg = 80 + CamSignature ' 0x50 Number of Objects of Signature
I2CCamWriteByte = 1 + 0
I2CCamWriteData = Vector.Init(I2CCamWriteByte, I2CCamReg)
I2CCamReadByte = 5
I2CCamReadData = Vector.Init(I2CCamReadByte, 0)
I2CCamReadData = Sensor.CommunicateI2C(I2CCamPort, I2CCamAddr, I2CCamWriteByte, I2CCamReadByte, I2CCamWriteData)
CamCount[CamSignature] = I2CCamReadData[0]
CamPosX[CamSignature] = I2CCamReadData[1]
CamPosY[CamSignature] = I2CCamReadData[2]
CamSizeX[CamSignature] = I2CCamReadData[3]
CamSizeY[CamSignature] = I2CCamReadData[4]
EndFor
EndSub
Sub ReadIR
I2CIRReg = 66 ' 0x42 Ambient Temperature Celcius (2 bytes LoHi) & 0x44 Target Temperature Celcius (2 bytes LoHi)
I2CIRWriteByte = 1 + 0
I2CIRWriteData = Vector.Init(I2CIRWriteByte, I2CIRReg)
I2CIRReadByte = 4
I2CIRReadData = Vector.Init(I2CIRReadByte, 0)
I2CIRReadData = Sensor.CommunicateI2C(I2CIRPort, I2CIRAddr, I2CIRWriteByte, I2CIRReadByte, I2CIRWriteData)
IRAmbient = (I2CIRReadData[1]*256 + I2CIRReadData[0]) / 100.0
IRTarget = (I2CIRReadData[3]*256 + I2CIRReadData[2]) / 100.0
EndSub
' ** Main Program Starts Here *******************************************************************************************************
LCD.Clear()
LCD.Write( 0*8, 0*10, "PixyCam & IR Test")
LCD.Write( 0*8, 2*10, "Cam Port: " + I2CCamPort)
LCD.Write(12*8, 2*10, "Address: " + I2CCamAddr)
LCD.Write( 0*8, 4*10, "Cam 1 Pos :")
LCD.Write( 0*8, 5*10, "Cam 1 Size:")
LCD.Write( 0*8, 7*10, "Cam 2 Pos :")
LCD.Write( 0*8, 8*10, "Cam 2 Size:")
LCD.Write( 0*8, 10*10, "IR Port: " + I2CIRPort)
LCD.Write(11*8, 10*10, "Address: " + I2CIRAddr)
LCD.Write( 0*8, 12*10, "IR Amb,Tar:")
While Finished = "False"
ReadCamera()
LCD.Write(12*8, 4*10, Text.GetSubText(" " +CamCount[1],Text.GetLength(CamCount[1]),2))
LCD.Write(15*8, 4*10, Text.GetSubText(" "+CamPosX [1],Text.GetLength(CamPosX [1]),3))
LCD.Write(19*8, 4*10, Text.GetSubText(" "+CamPosY [1],Text.GetLength(CamPosY [1]),3))
LCD.Write(15*8, 5*10, Text.GetSubText(" "+CamSizeX[1],Text.GetLength(CamSizeX[1]),3))
LCD.Write(19*8, 5*10, Text.GetSubText(" "+CamSizeY[1],Text.GetLength(CamSizeY[1]),3))
LCD.Write(12*8, 7*10, Text.GetSubText(" " +CamCount[2],Text.GetLength(CamCount[2]),2))
LCD.Write(15*8, 7*10, Text.GetSubText(" "+CamPosX [2],Text.GetLength(CamPosX [2]),3))
LCD.Write(19*8, 7*10, Text.GetSubText(" "+CamPosY [2],Text.GetLength(CamPosY [2]),3))
LCD.Write(15*8, 8*10, Text.GetSubText(" "+CamSizeX[2],Text.GetLength(CamSizeX[2]),3))
LCD.Write(19*8, 8*10, Text.GetSubText(" "+CamSizeY[2],Text.GetLength(CamSizeY[2]),3))
ReadIR()
If Math.Remainder((IRAmbient*100), 100) = 0 then
LCD.Write(11*8, 12*10, Text.GetSubText(" "+IRAmbient,Text.GetLength(IRAmbient),2)+".00")
ElseIf Math.Remainder((IRAmbient*100), 10) = 0 then
LCD.Write(11*8, 12*10, Text.GetSubText(" "+IRAmbient,Text.GetLength(IRAmbient),4)+"0")
Else
LCD.Write(11*8, 12*10, Text.GetSubText(" "+IRAmbient,Text.GetLength(IRAmbient),5))
EndIf
If Math.Remainder((IRTarget*100), 100) = 0 then
LCD.Write(17*8, 12*10, Text.GetSubText(" "+IRTarget,Text.GetLength(IRTarget),2)+".00")
ElseIf Math.Remainder((IRTarget*100), 10) = 0 then
LCD.Write(17*8, 12*10, Text.GetSubText(" "+IRTarget,Text.GetLength(IRTarget),4)+"0")
Else
LCD.Write(17*8, 12*10, Text.GetSubText(" "+IRTarget,Text.GetLength(IRTarget),5))
EndIf
Clicks = Buttons.GetClicks()
If Text.IsSubText(Clicks, "E") Then
Finished = "True"
EndIf
EndWhile
Conclusions
Just a few comments to finish with:
- If you wish to use Fahrenheit instead of Celsius the documentation shows which registers to change in the code.
- The PixyCam can detect up to 7 colour signatures and the code can be modified to return the other signatures if desired.
- Attempting to use the Mindsensors Pixy Adapter for Mindstorms EV3 or NXT failed to work because EV3 Basic does not support daisy chaining of I2C devices. To work with EV3 Basic we needed to talk directly to the PixyCam and not through an adapter.
For more information on robotics and the EV3 Basic extensions to Microsoft Small Basic, check out the following links:
This completes the current series of robotics articles. Please let me know what you would like as a topic for future articles on robotics or EV3 Basic.
David
This article was originally posted on http://www.winthropdc.com/blog.
Filed under: Development, EV3 Basic, Robotics, Small Basic Tagged: Development, EV3 Basic, Lego Mindstorms, Robotics, Small Basic
This was originally posted here.

Like
Report

*This post is locked for comments