Can Electrical Noise Cause Global Variables to Dramatically Change?
SteveWoodrough
Posts: 190
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