Shop OBEX P1 Docs P2 Docs Learn Events
Can Electrical Noise Cause Global Variables to Dramatically Change? — Parallax Forums

Can Electrical Noise Cause Global Variables to Dramatically Change?

SteveWoodroughSteveWoodrough Posts: 190
edited 2013-10-02 18:09 in General Discussion
Alright, excluding some bonehead coding error, this should be a good one.

I’m 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 Hanno’s 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. I’ve 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 &#8594; 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

  • ElectrodudeElectrodude Posts: 1,658
    edited 2013-09-29 19:15
    Make PWMStack bigger. 10 longs is way too small. You're having a stack overflow, which is attacking your other variables. Make PWMStack at least 128 longs at first, and decrease that until it doesn't work anymore. After you find the lowest number it works at, use something slightly higher than that.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2013-09-29 19:48
    Good advice, but No Joy. Bumped up to 256 with no effect. Thanks! Steve
  • kwinnkwinn Posts: 8,697
    edited 2013-09-29 23:33
    Electrical noise can cause problems like that if it is bad enough. It can come from many sources but motors and coils on relays and solenoids.are the most common source. Keep signal cables away from power runs, make sure coils have working diodes on them, and run logic from a separate supply if possible.
  • Mark_TMark_T Posts: 1,981
    edited 2013-09-30 04:56
    Almost certainly noise from the motor circuitry causing spikes on your logic inputs - logic inputs only need 10ns of spike to register.

    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.
  • Mike GMike G Posts: 2,702
    edited 2013-09-30 05:44
    I noticed the methods that read serial data, ReadIntBT, do not validate the data before returning a value. The method blindly return the next 4 bytes in the buffer. While noise can be the culprit, the code lets the noise filter through to the control logic.

    Never trust data coming from anywhere.
  • PropGuy2PropGuy2 Posts: 360
    edited 2013-09-30 08:23
    I have had the same problem with VGA video drivers. After checking evrything in my code and putting a scope on the sync pulses, I found that the WORDMOVE command used in two or more cogs causes no end of problems. This ONLY occurs with the new Prop Project Board USB(32810 rev.A/B) - my Professional Development Board (32111) and older/retired Prop Proto Board (32812) work perfectly, with exactly the same setup & same code. I have tried shielding, bigger stacks, tweeking the code, you name it.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2013-10-02 18:09
    Thank YOU for you comments and suggestions. I twisted the motor leads and looped them through a choke. That seemed to fix the worst of the glitches. I will try to slow down the baud rate so that glitches look less like data. @Mike G, (or anyone) mentioned validating the data before returning a value. The only thing I can think of is to compare the latest value with the previous value and reject if it is beyond some threshold. Is that what you are recommending? Is there some other technique for data validation I should consider?
    Thank You,
    Steve
Sign In or Register to comment.