Lowering the voltage on a spike

Is there a way to lower the voltage on a spike.
The spike drives a window motor but the motor is turning too fast. I want the spikes on/off function, but slower.

you need to use a Victor. You can turn it “on” and “off” plus control the speed of your motor by plugging it into a PWM port. Sending a 127 signal is “off”. 128-254 is variable speed in one direction while 0-126 is variable speed in the other direction.

yea, you’re not gonna be able to do it with out using a PWM.
basically it goes like this:
spike = on/off switch
pwm = dimmer

you’re only other option is to play with the gear ratios (smaller gear, sprocket, pulley, w.e. on the window motor and/or larger gear, sprocket, pulley, w.e. on whatever is being driven.

probably, the easiest thing to do is to swap the spike for a pwm

You could use a bunch of the highest gauge wire available.

Actually, I believe that would be illegal… :rolleyes: Electrical gurus?

You’re gonna have to switch over to a Victor.

Can you not send a series of on/off pulses through the spike? I am sure its probably a bit harsh on the motor.

Both this idea and the victor technically wouldn’t limit the actual voltage, just the duty cycle of the signal.

how about something like this…

if button is pushed (p1_sw_trig)
( pwm01 = 155; //turn slow)
if button is pushed (p1_sw_top)
( pwm01 = 110; //turn slow backward)

What would this code actually look like?

The problem is that using a spike makes writing my code alot easier. Wiring the motor through a victor, (which we have already done) is possible but not now

I’m pretty sure that the Spike cannot operate at high frequencies like a Victor. If I remember right, the max cycling is like 20hz for just a few seconds. The Victors are solid state, but the spikes are actually a mechanical relay- thats the clicking noise. This limits the frequency as well as the life cycles that the unit can handle. Otherwise, I think your idea is right, just not with our hardware.

For your own sanity, please don’t just say ‘pwm01 = 155; // slow forward.’
do this instead:

#define DRIVE_SLOW_FWD 155
#define DRIVE_SLOW_REV 99

// other code...


For one, it saves you a comment every time you use that value
for two, if you ever want to change the value, you don’t have to find’n’replace 155

But, to allow you to save face, I’m going to assume that you replaced your #define or equivalent with 155 when you pasted for clarity.
This comment was directed toward new programmers.

As was mentioned above, the Spikes are relays and only exhibit forward/off/reverse functionality. There is no slow speed. It’s all or nothing. If you want a slower speed, you either need to change your gearing (probably not an option) or use a Victor to variably control your speed.

I don’t understand your comment about the code being harder. It is essentially the same code, just on a different port (pwm vs relay).

For a relay, you probably have

relay1_fwd = 1;

whereas for a speed controller you would have what meatmanek suggested.


If you could clarify what you think would be harder, we may be able to offer up some better suggestions.

And even harder on the Spike. Solid state or not, switching an inductive load isn’t pretty.

But you definitely have the theory right!

Plus what Andrew said ^^


If you’re looking for code on how to pulse-width modulate the spikes so that you can decrease the speed, it can be done. However, realize that the spikes are mechanical devices, and switching them on and off wears them down. Normally, this isn’t a problem, but it will be if you’re switching them on and off once every second. The solution for the problem is to go to a solid state system - the Victor.

Now, if you’re trying to run it slowly sometimes and quickly other times, you’ll want to go with a Victor.

If you’re trying to run it more slowly all of the time, the best solution might just be to change the gear ratio so you have more torque.

The drives been built. so I can’t change the gears on the motors.
Just so I don’t look like an absolute ignoramus, I do know how a spike and victor work, I just want to know if its possible.

I know I’m not C savy, so things like
#define DRIVE_SLOW_FWD 155
#define DRIVE_SLOW_REV 99

// other code…


always seems like an extra step that I don’t have to do, especially when I can just say pwm01=155 and put in a comment on the side that reminds me what the line is actually doing.

the window turns a motor until it hits a switch. If I use a relay I can use
relay1_fwd = p1_sw_trig & rc_dig_in01; /* FWD only if switch1 is not closed. /
relay1_rev = p1_sw_top & rc_dig_in02; /
REV only if switch2 is not closed. */
in the default code and it will do exactly what I need. (ex. turn right until the switch is hit–rc_dig_in01–, not be able to turn right anymore right, but will be able to turn left until it hits the other switch–rc_dig_in02–)
but of course the motor turns too fast.

If I wire the window to a victor then I have to write new code (thread–Programming a switch) to control the victor in the same fashion. I may have to do it this way, which was a little bit beyond my C skills.
So I decided to go the other route and see if there was a way of just slowing down a victor, but apparently not.
but I might be able to program a victor to work of a joystick button

They rate a Spike at only 6 switches/minute with a load. I would seriously consider a Victor. It’s your best option between a lot of high gauge wire or any other options posted here other than the victor idea.

Okay, I’m not sure if this will help you a lot, but I recently reprogrammed our 2003 robot. This robot uses PBASIC and not C, but this will give you a general idea if you know anything about If Then statements, which I assume you do. All you need to do is set:
pwm1 = 127 ‘for off’
pwm1 = 0 ‘for full reverse/forward’
pwm1 = 254 ‘for full forward/reverse’

Use the If then statements to set the limits for the motor. Once these limit switches are closed, set the pwm1 signal to 127 to stop the motor. You can use anything from 0-126 for one direction or 128-254 for the other direction, and of course the closer you get to 127, the slower the motor turns. I wish I had the code I made last week for our robot, it’s an excellent example on what to do. In our application we had a motor controlling a shifter with 2 limit switches on the shifting rod. The robot would set the shifter to 1 or 0 by the use of the joystick and would keep it at 1 or 0 infinitely until the joystick button had been pressed to turn a different direction or if the robot had been turned off.

Thanks Ryan, could you post your sample code?

That may be true in small simple cases, but as soon as you start getting more complicated and using the same value all over the place it will make your life easier. For example, if you look in ifi_aliases.h, you’ll find

#define pwm01           txdata.rc_pwm01

Now imagine if you didn’t have that alias in place and had to type txdata.rc_pwm01 all over the place. The same goes for constants. Lets say you had a program that was doing a bunch of operations on circles and you needed to use PI all over the place. You could hardcode each line of code to have 3.14, but what happens if you want more precision? You have to search and replace all the 3.14’s with 3.1415. If you had a constant, you would only have to change it in one place.

There’s no hard rule that says you have to use constants/macros, but they sure do make your life easier.

the window turns a motor until it hits a switch. If I use a relay I can use
relay1_fwd = p1_sw_trig & rc_dig_in01; /* FWD only if switch1 is not closed. /
relay1_rev = p1_sw_top & rc_dig_in02; /
REV only if switch2 is not closed. */
How about something like this?

#define DRIVE_SLOW_FWD 155
#define DRIVE_SLOW_REV 99
if((p1_sw_trig == 1) && (rc_dig_in01 == 1))
  pwm01 = DRIVE_SLOW_FWD;
else if((p1_sw_top == 1) && (rc_dig_in02 == 1))
  pwm01 = DRIVE_SLOW_REV;
  pwm01 = 127;

A couple of notes:

  • The above code assumes that the digital ins report a 1 when the switch is not pressed
  • You’ll notice that I made explicit comparisons to 1 to determine the switch states. This is for readability and ease of maintenance. I can quickly go in and change a 1 to a 0 and get different behavior. Yes, I could just add a ! before the variable, but then it changes the visual flow of the code.
  • You’ll also notice that I’m doing a boolean and (&&) instead of a bitwise and (&). While the operation in this case is identical, it’s a good habit to get into.
  • There is a small error case that is not handled. What happens if both buttons are pressed at the same time? The FWD case will dominate until the switch is pressed then the REV case will take over. As soon as switch 1 is released it will drive FWD again.

Hope this helps

As it relates to an earlier question in this post. There is no limit on the length of wire you may use on your robot. As long as the wire size is protected by the specified breaker you may do what ever seems to make it work. However, at a window motor operating current of 2 amps you would need to add 100’s of feet of wire to you robot to achieve a reduction in current.

Relays are not happy switching quickly (>2 or 3 Hz) and get really unhappy when the load is inductive, i.e. motors. The switching current causes some arcing as the contacts break open which eventually leads to pitting of the contact surface. Since this damage has a dominoe effect, the eventual failure can be either a permanent open or a permanent close. Neither are desirable. Your only alternative seems to be a change in gearing or a swtich to Victor. Sorry.

And of course, whether you choose to go with a victor or a gear ratio reduction depends on a few things:

If you could use the extra torque (who couldn’t?), go with a gear reduction
If your mechanism isn’t designed to take changes in chain length like that, (this happened to us a few years back), go with a Victor.

If you can afford the extra weight of a victor, but never need to go as fast as you can right now, and a gear reduction is simple, do both. The variable power output of a Victor is always nice, it allows for things such as PID.