Struggling with writing to and reading from EEPROM

abenn

Senior Member
I have a very simple program which moves a standard RC servo slowly from one resting position to another at the throw of a switch; switch closed = full right; switch open = full left. Each time the servo is moved the program is supposed to save its position (1 = right; 2 = left) into the EEPROM so that, when power is switched on again after having been switched off, the servo will go slowly to whichever position the switch is in at that moment -- even if the switch has been changed while the power was off. The program works fine so long as power is there, but when power is switched off and then switched on again, whether or not the switch is in the correct position for the present servo position, the servo jerks through about 10 degrees of rotation, and doesn't move to a correct position until the switch is thrown one way or the other.

c.1 and c.4 switch leds to indicate the position of the servo, and a relay, neither of which impact on the operation of the servo itself. I switch the servo OFF after each movement to eliminate buzzing while it's stationary, and to save power, so it shouldn't even be responsive when I power up the circuit.

Following is the program; can anyone enlighten me as to why the servo gives such a twitch when the circuit is powered up, please? Maybe it's nothing to do with the memory, but a "spike" or something affecting the servo? If so, how can I eliminate that?

Code:
symbol servo_position = b5
symbol min_pulse = b6
symbol max_pulse = b7
symbol servo_slow = b8
symbol route_set = b9

let max_pulse = 175  	;change this value to alter right limit
let min_pulse = 125   	;change this value to alter left limit
let servo_slow = 20	;increase this value to slow servo

SYMBOL EEPROM_Save = 1  ;defines EEPROM location 1 to hold current selected route

read EEPROM_Save,route_set


main:

	if pin3 = 1 and route_set<>1 then
	  let servo_position=min_pulse 
	  goto rightA
	elseif pin3 = 0 and route_set<>2 then
	  let servo_position=max_pulse
	  goto leftA
	else
	  goto main
	endif
	
rightA:

	high c.1
	high c.4
		
	servo c.2,servo_position
	inc servo_position
	pause servo_slow
	do 
	  servopos c.2,servo_position
	  inc servo_position
	  pause servo_slow
	loop while servo_position<max_pulse
	let servo_position=max_pulse
	let route_set=1
	write EEPROM_Save,route_set
	pause 10
	servo c.2,OFF
	
	low c.1
	
	goto main
	
leftA:

	high c.1
	high c.4
	
	servo c.2,servo_position
	dec servo_position
	pause servo_slow
	do
	  servopos c.2,servo_position
	  dec servo_position
	  pause servo_slow
	loop while servo_position>min_pulse
	let servo_position=min_pulse
	let route_set=2
	write EEPROM_Save,route_set
	pause 10
	servo c.2,OFF
	
	low c.4
	
	goto main
 

hippy

Technical Support
Staff member
Not entirely sure. Your EEPROM reading and writing look okay so it is perhaps the logic of your code. Perhaps you could step through it using the PE6 simulator to see if it does what would be expected.

The glitch could simply be what happens with the servo when you turn on the PICAXE and then enable the servo pulses. You might have to write additional test code to see if that is the case.
 

abenn

Senior Member
Thanks hippy.

After posting I realised I should have checked the servo by itself first, and when I simply apply 5v to its power leads, sure enough it glitches just like when I use my program to run it.

So it looks like I'll have to experiment with a routine that applies a signal to it simultaneous with the power-up (if that can be done) to see if that cures it -- or write a further preliminary routine to cycle it during boot-up so that it ends up in the correct position.
 

Circuit

Senior Member
Servo glitches on power-up can sometimes be minimised by placing a pull-up or a pull-down resistor (say 10K) permanently onto the signal lead. Which? Apparently it depends upon the servo - cannot do much harm to try each. This ensures that the signal lead is never left floating and/or receiving noise.
 
Servo glitches on power-up can sometimes be minimised by placing a pull-up or a pull-down resistor (say 10K) permanently onto the signal lead. Which? Apparently it depends upon the servo - cannot do much harm to try each. This ensures that the signal lead is never left floating and/or receiving noise.
Servo wiring colour code attached. In my experience all RC servos twitch on power up.
 

Attachments

eggdweather

Senior Member
What type of servo are you using - part no/name.

I fly model aircraft and none of mine do that, but then I use digital servos that save their last known position, it's used for conditions during signal lost, so that the aircraft does not flutter or perform unwanted actions during a momentary signal loss, you don't need to spend much for a digital servo e.g. £6.83 http://www.hobbyking.com/hobbyking/store/__8303__Hextronik_MG_14_14g_2_6kg_0_11sec_Digital_Aircraft_Servo.html

Also, I think your programme needs to be saving the last known position in EEPROM and then during initialisation issue a servo command that gives the servo a point of reference before a switch is actuated.
 

abenn

Senior Member
I fly model aircraft too and, now that I think of it, most of my servos twitch when I switch on the receiver. They almost immediately settle down, but that's because the receiver's continuously sending a position signal to them. I could modify the program to drive the servo to the correct position at initialisation, but I'm really trying to avoid the twitch in the first place because this application is to drive the points on my model railway.

Your comment about digital servos is interesting eggdweather: Up until now I've been using the cheapest HobbyKing mini servos I can find (HK1517B), but I've just tried my circuit with a Hitec HS-5055MG digital servo and, as you suggest, it doesn't twitch -- it works just as I want, moving (or not, as the case may be) to whichever position the switch is set for. I'm going to check out one of the digital version of the HK servos to see if that behaves like the Hitec one does.
 

eggdweather

Senior Member
Good to hear that might solve your problem, I've always used the cheaper end of the digital servos and they don't twitch like the old analogue ones, some of them have a memory for fail-safe purposes and drive themselves to a pre-programmed position, I don't use that type preferring to use the Rx to do that on signal loss. I'm sure you've noticed how powerful they are.

I'm currently flying a 3D Parkzone VisionAire which has huge control surfaces and massive throws and any unwanted movement on that would be a disaster and the supplied servos (EFlite 13gram digital variants) don't twitch.
 

abenn

Senior Member
One of my objectives was to keep the cost down to around or below what traditional model railway point motors (basically a large solenoid) cost, hence the original HK analogue servos. But I've just ordered a couple of the digital version of the same servo, and I'll let you know how they fare.
 

hippy

Technical Support
Staff member
The program works fine so long as power is there, but when power is switched off and then switched on again, whether or not the switch is in the correct position for the present servo position, the servo jerks through about 10 degrees of rotation, and doesn't move to a correct position until the switch is thrown one way or the other.
I think there may be two issues here; the initial power on glitch but also some issue with the program that the servo does not end up positioned where it should be once the servo pulses are being provided.

It might be worth restructuring the code to make it easier to follow and debug, for example, something like -

Code:
Read EEPROM_Save, route_set

If route_set = "L" Then
  Gosub MoveToLeft
Else
  Gosub MoveToRight
End If

Do
  If pin3 = 0 and route_set <> "L" Then
    Gosub MoveToLeft
  End If
  If pin3 = 1 and route_set <> "R" Then
    Gosub MoveToRight
  End If
Loop

MoveToLeft:
  route_set = "L"
  Servo C.2, max_pulse
  For servo_position = max_pulse To min_pulse Step -1
    ServoPos C.2, servo_position
    Pause servo_slow
  Next
  Goto StopServo

MoveToRight:
  route_set = "R"
  Servo C.2, min_pulse
  For servo_position = min_pulse To max_pulse Step 1
    ServoPos C.2, servo_position
    Pause servo_slow
  Next
  Goto StopServo

StopServo:
  Write EEPROM_Save, route_set
  Pause 100
  Servo C.2, OFF
  Return
 

abenn

Senior Member
Thanks for taking the time hippy.

As it happens I think I've come up with basically the same solution: I figured that, since I can't prevent the power-up twitch (with analogue servos anyway), I might as well add an init: routine that first of all sends the servo to the mid position, then moves it left or right according to the switch position -- just like your first If ... End If routine. By going to the mid position first it ensures that the servo won't travel from one extreme to the other at full speed if the switch position has changed since it was last powered down. I've tested it this afternoon on my rail layout, and it's working fine, so no further refinement needed.
 
Top