Can Electrical Noise Cause Global Variables to Dramatically Change?
Alright, excluding some bonehead coding error, this should be a good one.
Im playing with RoboRealm (RR) and using Blue Tooth (BT) to control a toy tracked bot. The bot is a hacked toy that drives two tank treads using the Dual Motor Driver MC33926 to drive two small can motors. Real simple stuff, forward, left and right pivots based on mouse or Track Point movement. RoboRealm takes the data from the PC,Mouse_X and Mouse_Y, and sends it out the BT (com port). The BT on the bot picks up the data, and makes the moves based on a few IF statements.
Using Hannos ViewPort (VP), I can easily monitor the data received into the Prop. Likewise in RR I can display and monitor the Mouse_X and Mouse_Y position values.
With the track motors powered off, the Mouse_X and Mouse_Y variable data is very well synchronized. The values shown in VP are closely following those shown in RR. The BT module is communicating and all is right with the world. I can move the mouse around for 5 minutes or more and the data stays synced. If I turn on the motor power, the motors spool up and react to the Mouse values as programmed. Pivot left, pivot right, forward slow, fast, etc. all just Okey dokey.
Then all of the sudden BLAMMO!! The Mouse_X and Mouse_Y values in the Prop as reported by VP go OFF the scale! Huge numbers, and the bot heads straight for the nearest object it can damage or that can inflict the most severe damage to the bot. Ive since put value limiters in the code, but the effect is nearly the same, an out of control bot.
In a few moments, the Mouse variable values in VP match those in RR and the situation is calm. Then, BOOM off they go again.
Nearest I can figure, there is electrical noise that is causing the variables to change. Is that possible? Any ideas?
Best Regards,
Steve
Im playing with RoboRealm (RR) and using Blue Tooth (BT) to control a toy tracked bot. The bot is a hacked toy that drives two tank treads using the Dual Motor Driver MC33926 to drive two small can motors. Real simple stuff, forward, left and right pivots based on mouse or Track Point movement. RoboRealm takes the data from the PC,Mouse_X and Mouse_Y, and sends it out the BT (com port). The BT on the bot picks up the data, and makes the moves based on a few IF statements.
Using Hannos ViewPort (VP), I can easily monitor the data received into the Prop. Likewise in RR I can display and monitor the Mouse_X and Mouse_Y position values.
With the track motors powered off, the Mouse_X and Mouse_Y variable data is very well synchronized. The values shown in VP are closely following those shown in RR. The BT module is communicating and all is right with the world. I can move the mouse around for 5 minutes or more and the data stays synced. If I turn on the motor power, the motors spool up and react to the Mouse values as programmed. Pivot left, pivot right, forward slow, fast, etc. all just Okey dokey.
Then all of the sudden BLAMMO!! The Mouse_X and Mouse_Y values in the Prop as reported by VP go OFF the scale! Huge numbers, and the bot heads straight for the nearest object it can damage or that can inflict the most severe damage to the bot. Ive since put value limiters in the code, but the effect is nearly the same, an out of control bot.
In a few moments, the Mouse variable values in VP match those in RR and the situation is calm. Then, BOOM off they go again.
Nearest I can figure, there is electrical noise that is causing the variables to change. Is that possible? Any ideas?
Best Regards,
Steve
Obj
FDSP : "FullDuplexSerialplus"
SERVO : "Servo32v7.spin"
FDS : "FullDuplexSerial4port" 'SEPARATE COG (3) Standard library object used with LCD and GPS
dio : "dataIO4port" 'Object supports the transmission of numerical data through UARTS
' PC : "Propeller_Communicator"
vp: "Conduit"
CON
_CLKMODE=XTAL1 + PLL16X ' The system clock spec
_XINFREQ = 5_000_000 ' Crystal
CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
MS_001 = CLK_FREQ / 1_000
US_001 = CLK_FREQ / 1_000_000
ServoPinX = 4
ServoPinY = 2
PST = 0 ' Port for Communication to PST
LCD = 1 ' Port for Communication to LCD Tx only
GPSPort = 2 ' Port for Communication to GPS Rx only
BT = 3 ' Port for
PST_BAUD = 115_200 ' PST baud rates, debug to terminal
LCD_BAUD = 19_200 ' LCD baud rate
GPS_BAUD = 9_600 ' GPS baud rate
BT_BAUD = 115_200 ' BT baud rate
'Pin Assignements:
BTTx = 25'0 'Tx Pin for Blue Tooth Module
BTRx = 24'1 'Rx Pin for Blue Tooth Module
MotorPin = 3
LCD_TXPIN = 4 ' LCD Tx pin
LCD_RXPIN = -1 ' LCD Rx pin THERE IS NONE
SteerPin = 5 'Output Pin connection for the RC Truck Servo
GPS_TXPIN = 14 ' GPS Tx
GPS_RXPIN = 15 ' GPS Rx pin
PST_TXPIN = 16'30 ' PST Tx Pin
PST_RXPIN = 17'31 ' PST Rx Pin
#1, HOME, #8, BKSP, TAB, LF, CLREOL, CLRDN, CR, #16, CLS ' PST formmatting control
M2FB = 0 '(Feedback of current draw - not used in this basic demo)
M2SF = 0 '(Status Flag - Not used in this basic demo)
M2D1 = 10 '(PWM), (GND - OVERRIDE), (Motor 2, Disable 1)
M2D2Pin = 9 'PWM input pin '(PWM), (VDD - OVERRIDE), (Motor 2, Disable 2)
M2IN1Pin = 8 '(Motor 2, Input 1)
M2IN2Pin = 7 '(Motor 2, Input 2)
INV = 0 '(VDD - OVERRIDE), (Not used in this basic demo)
SLEW = 0 '(VDD - OVERRIDE), (Not used in this basic demo)
EN = 0 'Using Jumper (VDD - OVERRIDE), (Enable - connect to Vin to enable carrier)
M1FB = 0 '(Feedback of current draw - not used in this basic demo)
M1SF = 0 '(Status Flag - not used in this basic demo)
M1D1 = 3 '(PWM), (GND - OVERRIDE) (Motor 1, Disable 1)
M1D2Pin = 2 'PWM input pin '(PWM), (VDD - OVERRIDE) (Motor 1, Disable 2)
M1IN1Pin = 1 '(Motor 1, Input 1)
M1IN2Pin = 0 '(Motor 1, Input 2)
MinSpeed = 200
MaxSpeed = 800
MidX = 320 'Robo Realm MidPoint X direction
MidY = 240 'Robo Realm MidPoint Y direction
var
long tHa,tHb 'tHa and tHb are used for PWM values
Long PWMStack[10] 'Stack Space to run PWM operation
Byte PWMCog 'Cog to Run PWM Method
Byte M11,M12,M21,M22 'Values set to 0 or 1 to control motor direction
Long a,Mouse_X, Mouse_Y,z
PUB Initialize |index
vp.share(@a, @z) 'Share global variables with ViewPort
' fds.start(31, 30, 0, 115_200)
Start_PWM 'Starts PWM generator is it's own cog
start_uarts 'Starts FDS4 Port
'FDSP.start(BTTx,BTRx,0,BT_BAUD) 'Tested successfully using FDSPlus Had to reset connections and reinstall BT module
'FDSP.start(PST_RXPIN,PST_TXPIN,0,PST_BAUD) 'Tested successfully using FDSPlus using cable
Main
Pub Main
MoveBT 'Move the bot based on using the BT module.
Pub MovePST
'CABLE VERSION
Repeat
Mouse_X := ReadIntPST 'Grabs a 4 byte (32 bit) number use the \\[MOUSE_X] syntax in RoboRealm
Mouse_Y := ReadIntPST 'Grab the next 4 bytes (32 bit) number \\[MOUSE_X]\\[MOUSE_Y] in RoboRealm
If Mouse_Y > Mouse_X
Forward
ElseIf Mouse_X > MidX
PivotRight
Elseif Mouse_X < MidX
PivotLeft
PUB ReadIntPST | rxVal_1, rxVal_2, rxVal_3, rxVal_4 ,rxVal
'Grabbing bytes and making numbers using FDS4 syntax
'************ Use this sytax \\[MOUSE_X]\\[MOUSE_Y] in RoboRealm
rxVal_1 := fds.rx(PST) 'Grab first byte
rxVal_2 := fds.rx(PST) 'Grab second byte
rxVal_3 := fds.rx(PST) 'Grab third byte
rxVal_4 := fds.rx(PST) 'Grab fourth byte
rxVal := rxVal_1 | (rxVal_2<<8) | (rxVal_3<<16) | (rxVal_4<<24) 'Combine all 4 bytes to make a number
RETURN rxVal 'Return the decimal number
Pub MoveBT
'BT Version
Repeat
Mouse_X := ReadIntBT #> 0 <# 640 'Grabs a 4 byte (32 bit) number use the \\[MOUSE_X] syntax in RoboRealm
Mouse_Y := ReadIntBT #> 0 <# 480 'Grab the next 4 bytes (32 bit) number \\[MOUSE_X]\\[MOUSE_Y] in RoboRealm
If Mouse_Y > Mouse_X
Forward
ElseIf Mouse_X > MidX
PivotRight
Elseif Mouse_X < MidX
PivotLeft
' Mouse_X := 0 'Reset Value in case it gets corrupted
' Mouse_Y := 0
PUB ReadIntBT | rxVal_1, rxVal_2, rxVal_3, rxVal_4 ,rxVal
'Grabbing bytes and making numbers using FDS4 syntax
'************ Use this sytax \\[MOUSE_X]\\[MOUSE_Y] in RoboRealm
rxVal_1 := fds.rx(BT) 'Grab first byte
rxVal_2 := fds.rx(BT) 'Grab second byte
rxVal_3 := fds.rx(BT) 'Grab third byte
rxVal_4 := fds.rx(BT) 'Grab fourth byte
rxVal := rxVal_1 | (rxVal_2<<8) | (rxVal_3<<16) | (rxVal_4<<24) 'Combine all 4 bytes to make a number
RETURN rxVal 'Return the decimal number
PUB Start_PWM 'Starts Cruise Control
Stop_PWM 'Prevent multiple starts
PWMCog := cognew(PWM, @PWMStack)+1 'Launch method in separate COG
PUB Stop_PWM ' 'Stops PWM
if PWMCog
cogstop(PWMCog~ -1) 'Stop previously launched cog
Pub PWM |t,tC,us
us := clkfreq/1_000_000 ' <- Add
tC := 1_000 * us
dira[0..3]~~ ' Main Cog - Set direction of Pins 0-3 to output (Controls for Motor 1)
dira[7..9]~~ ' Main Cog - Set direction of Pins 7-10 to output (Controls for Motor 2)
ctra[30..26] := ctrb[30..26] := %00100 ' Counters A and B → NCO single-ended
ctra[5..0] := M1D2Pin ' Set pins for counters to control
ctrb[5..0] := M2D2Pin
frqa := frqb := 1 ' Add 1 to phs with each clock tick
t := cnt ' Mark current time.
repeat
outa[M1IN1Pin]:= M11 'Defines direction 0101 is forward
outa[M1IN2Pin]:= M12
outa[M2IN1Pin]:= M21
outa[M2IN2Pin]:= M22
phsa := -tHa * us ' Define and start the A pulse
phsb := -tHb * us ' Define and start the B pulse
t += tC ' Calculate next cycle repeat
waitcnt(t)
'NOTE: Above settings turn both motors in Forward directon. Switching the settings on Pins 0 & 1 will reverse
' the direction of Motor 1. Switching the settings on Pins 7 & 8 will reverse the direction of Motor 2.
' Changing setting of Pin 15 will disable the entire board. Changing setings on Pis 3 and 10 can disable
' the individual motors.
Pub PivotLeft
M11 := 1
M12 := 0
M21 := 0
M22 := 1
tHa:= 2*(MidX - Mouse_X)
tHb:= tHa
Pub PivotRight
M11 := 0
M12 := 1
M21 := 1
M22 := 0
tHa:= 2*(Mouse_X-MidX)
tHb:= tHa
Pub Forward
M11 := 0
M12 := 1
M21 := 0
M22 := 1
tHa:= Mouse_Y/2' MaxSpeed
tHb:= Mouse_Y/2' MaxSpeed
Pub Flank
M11 := 0
M12 := 1
M21 := 0
M22 := 1
tHa:= 1000
tHb:= 1000
Pub Stop
M11 := 0
M12 := 1
M21 := 0
M22 := 1
tHa:= 0
tHb:= 0
Pub Ramp
M11 := 0
M12 := 1
M21 := 0
M22 := 1
repeat tHa from (MinSpeed) to (MaxSpeed) ' <- Change Repeat PWM signal
tHb:=tHa
waitcnt(clkfreq/100+cnt)
PUB start_uarts
'' port 0-3 port index of which serial port
'' rx/tx/cts/rtspin pin number #PINNOTUSED = -1 if not used
'' prop debug port rx on p31, tx on p30
'' cts is prop input associated with tx output flow control
'' rts is prop output associated with rx input flow control
'' rtsthreshold - buffer threshold before rts is used #DEFAULTTHRSHOLD = 0 means use default=buffer 3/4 full
'' note rtsthreshold has no effect unless RTS pin is enabled
'' mode bit 0 = invert rx #INVERTRX bit mask
'' mode bit 1 = invert tx #INVERTTX bit mask
'' mode bit 2 = open-drain/source tx #OCTX bit mask
'' mode bit 3 = ignore tx echo on rx #NOECHO bit mask
'' mode bit 4 = invert cts #INVERTCTS bit mask
'' mode bit 5 = invert rts #INVERTRTS bit mask
'' baudrate desired baud rate, e.g. 9600
fds.init ' sets up and clears the buffers and pointers, returns a pointer to the internal fds data structure
' always call init before adding or starting ports.
'****IMPORTANT NOTE: TURN OFF PST PORT IF YOU PLAN TO USE VIEW PORT.****
fds.AddPort(BT,BTTx,BTRx,-1,-1,0,0,BT_BAUD)
fds.AddPort(PST, PST_RXPIN, PST_TXPIN,-1,-1,0,0,PST_BAUD) ' debug to the terminal screen, without flow control, normal non-inverted mode
fds.AddPort(LCD, LCD_RxPIN, LCD_TXPIN,-1,-1,0,0,LCD_BAUD) ' Sends data to LCD screen
fds.AddPort(GPSPort, GPS_RxPIN, GPS_TXPIN,-1,-1,0,0,GPS_BAUD) ' Receive data from GPS
' port 1, 2, 3 are not used. The order that you define ports does not matter. You don't have to do anything to set up unused ports
fds.Start
pause(1000) ' delay to get going before sending or receiving any data

Comments
Never run power wiring alongside sensor wiring, always used shielded cable or twisted pairs for signal cables, Always use twisted
pair for PWM'd power wiring. Its easy to make twisted pair using a hand-drill and a vice.
Never trust data coming from anywhere.
Thank You,
Steve