Controlling a solenoid with a L293d motor shield

Hello,

I want to use a L293d motor shield to drive a solenoid.

I know this has already been done before and I am trying to replicate this project. Only that I am trying to do something much simpler with only one board and one solenoid to begin with.

My solenoid is also smaller. It is home made solenoid which is only 4 mm in diameter and requires only 4.5V to operate, that I provide with an external power input. The resistance of the solenoid is about 1 ohm. So, I guess the current is about 1.1 Amp in the solenoid.

I am using the same code as the original project, except that I kept only the HARDWARE_TEST part.

During a code test run where I am calling allChannelOutput() for a long time, I measure 4.3 V with my multimeter on the shield motor pins. The solenoid works fine when I manually connect the wires to the shield outputs for a very short time.

However, when I finally connect the solenoid and call allChannelOutput() for only 100 ms (which is how the solenoid is supposed to be operated), the solenoid isn't activated. There does not seem to be enough current running through the solenoid.

Am I doing something wrong ?

Here is my code:

// Arduino pins for the shift register
#define MOTORLATCH   12
#define MOTORCLK     4
#define MOTORENABLE  7
#define MOTORDATA    8

// 8-bit bus after the 74HC595 shift register 
// (not Arduino pins)
// These are used to set the direction of the bridge driver.
#define MOTOR1_A 2
#define MOTOR1_B 3
#define MOTOR2_A 1
#define MOTOR2_B 4
#define MOTOR3_A 5
#define MOTOR3_B 7
#define MOTOR4_A 0
#define MOTOR4_B 6

// Arduino pins for the PWM signals.
#define MOTOR1_PWM 11
#define MOTOR2_PWM 3
#define MOTOR3_PWM 6
#define MOTOR4_PWM 5

#define SERIAL_BAUD_RATE      57600


// Array storing the 8-bit bus after the 74HC595 shift register
uint8_t motorBus[] = { MOTOR1_A , MOTOR1_B, MOTOR2_A , MOTOR2_B, 
                       MOTOR3_A , MOTOR3_B, MOTOR4_A , MOTOR4_B };

// Array storing the Arduino pins for the PWM signals
uint8_t motorPwmPins[] = { MOTOR1_PWM, MOTOR2_PWM, MOTOR3_PWM, MOTOR4_PWM };

// Used for Hardware Test mode (when HARDWARE_TEST = 1)
uint8_t testHardwareSolenoidCount;
uint8_t testHardwarePauseCount;


// ****************************************************************************
// setup() - Initialization Function
// ****************************************************************************
void setup()
{
  // Initialize Serial communication and Slave Address
  Serial.begin(SERIAL_BAUD_RATE);

  // Initialize Test Mode
  testHardwareSolenoidCount = 0;
}

// ****************************************************************************
// loop() - Main Program Loop Function 
// ****************************************************************************
void loop()
{
  // De-energize the solenoid
  allChannelOutput(0);
  delay(10000);
  // Energize the solenoid
  allChannelOutput(1 << testHardwareSolenoidCount);
  delay(100);
// De-energize the solenoid
  allChannelOutput(0);
  delay(10000);
}

// ****************************************************************************
// allChannelOutput() - Sets the state of all channels per 'outputChannels'
//     which is an 8-bit bitmask of the channels to be energized.
// ****************************************************************************
void allChannelOutput(uint8_t outputChannels)
{
  uint8_t i;
  uint8_t motorChannels;

  // Convert the bitmask of 'outputChannels', which corresponds to the
  // shield terminal channels 0 through 7, to the bitmask of the
  // 8-bit bus after the 74HC595 shift register
  for (i = 0; i < 8; i++)
    bitWrite(motorChannels, motorBus[i], bitRead(outputChannels, i));

  // Send the 8-bit bitmask to the Shift register
  shiftWriteAll(motorChannels);

  // Set the PWM Pins.  Each PWM pin is set to 255 (fully-on) if either
  // the corresponding A or B is on, and set to 0 (fully off) otherwise
  for (i = 0; i < 4; i++)
  {
    if(bitRead(outputChannels,2*i) || bitRead(outputChannels, 2*i+1))
      analogWrite(motorPwmPins[i], 255);
    else
      analogWrite(motorPwmPins[i], 0);
  }
}

// ---------------------------------
// shiftWriteAll
//
// A variant of the shiftWrite function
// Pass it the bitMask of all channels to be written.
// There is no initialization function.
// Initialization is automatically done at the first
// time it is used.
//
void shiftWriteAll(int outputBitmask)
{
  static int latch_copy;
  static int shift_register_initialized = false;

  // Do the initialization on the fly, 
  // at the first time it is used.
  if (!shift_register_initialized)
  {
    // Set pins for shift register to output
    pinMode(MOTORLATCH, OUTPUT);
    pinMode(MOTORENABLE, OUTPUT);
    pinMode(MOTORDATA, OUTPUT);
    pinMode(MOTORCLK, OUTPUT);

    // Set pins for shift register to default value (low);
    digitalWrite(MOTORDATA, LOW);
    digitalWrite(MOTORLATCH, LOW);
    digitalWrite(MOTORCLK, LOW);
    // Enable the shift register, set Enable pin Low.
    digitalWrite(MOTORENABLE, LOW);

    // start with all outputs (of the shift register) low
    latch_copy = 0;

    shift_register_initialized = true;
  }

  // The defines HIGH and LOW are 1 and 0.
  // So this is valid.
  //bitWrite(latch_copy, output, high_low);
  latch_copy = outputBitmask;

  // Use the default Arduino 'shiftOut()' function to
  // shift the bits with the MOTORCLK as clock pulse.
  // The 74HC595 shiftregister wants the MSB first.
  // After that, generate a latch pulse with MOTORLATCH.
  shiftOut(MOTORDATA, MOTORCLK, MSBFIRST, latch_copy);
  delayMicroseconds(5);    // For safety, not really needed.
  digitalWrite(MOTORLATCH, HIGH);
  delayMicroseconds(5);    // For safety, not really needed.
  digitalWrite(MOTORLATCH, LOW);
}

Attached is my super simple wiring.

How much current does the solenoid require?

Lot of voltage drop across an L293D. Might be too much, leaving too little voltage to drive the solenoid.

Post your wiring, I'd like to see how the 74HC595 and L293D are wired up with the solenoid.

For most solenoids a simple MOSFET might be a better option.

Posting tips.

  • Always list the version of the IDE you are using and the board version if applicable.
  • How to insert an image into your post. ( Thanks Robin2 )
  • Add your sketch where applicable but please use CODE TAGS ( </> )
  • Add a SCHEMATIC were needed even if it is hand drawn [/li]
    - Add working links to any specific hardware as needed (NOT links to similar items)
    - Remember that the people trying to help cannot see your problem so give as much information as you can
    [/list]

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

as already noted, all you need is a transistor that can handle the current. see this web page. Note that grounds the solenoid which can be driven by an external voltage source

Hello all,

First excuse me for my posting skills. I updated the original post with the right tags for the code and an image of my wiring.

The current in the solenoid should be 1.1 amp since it only has a resistance of 1 ohm.
The voltage drop of the shield is not the problem since I can operate the solenoid fine by manually connecting the solenoid to the M1 output of the shield. There is 4.3 V here which is enough.

I don't want to use a transistor because I need to reverse current in the solenoid and I thought the motor shield would be handy for that.

I only need to operate the solenoid with very short pulses of current. I don't need to maintain current in the solenoid.

The version of my IDE is Arduino 1.8.10.
My shield is this one.
My board is an Arduino Uno.

Thank you for your help.

Altaris:
The current in the solenoid should be 1.1 amp since it only has a resistance of 1 ohm.

I = V / R
I = 4.5 / 1
I = 4.5 Amps.
Tom... :slight_smile:

TomGeorge:
I = V / R
I = 4.5 / 1
I = 4.5 Amps.
Tom... :slight_smile:

Oups you're right ! Normal I can't make it work if I can't make a division right I guess.
Lucky I didn't burn the shield. Or maybe I have...

I'll try to see if I can operate the solenoid with a resistance to drop the current down.

instead of using a resistor to drop the voltage, why not use the correct voltage the solenoid is rated at?

the code seems excessive to control a single solenoid. Two pins need to be set to 1/0 or 0/1 to control the voltage polarity and analogWrite to the enable pin to control the voltage (PWM).

No OK, the resistance of the solenoid is not 1 ohm but 4.2 ohm. That's why I had in mind 1.1 amp !

I am not entirely senile yet.

The solenoid is not rated for anything because it's home made. Eventually, I will need to use 3 or 4 solenoids for my project.

Sorry for the confusion.

So I guess that if the L293d is rated for 1.2 amp peak, it's ok then ?

Is "because it's home made." leading to "I need to reverse current in the solenoid" because there is no spring to move the solenoid to the undriven position?

How is the 74HC595 wiring that your code refers to wired in?

Ah, I see, it's part of the shield. Can't read that website, not good reading French.

Hello CrossRoads,

There is no spring on my solenoid, but it's on purpose. I want it to be a bi-stable solenoid. So I don't want the solenoid to return back to it's rest position when there is no current. I am using a permanent magnet for the solenoid rode. Reversing the current allows for a pull/push action on the permanent magnet.

Yes, the 74HC595 is part of the shield. I am not much into electronics but I think this is a very common shield. Here is some documentation in English that might be useful for you.

gciurpita:
the code seems excessive to control a single solenoid. Two pins need to be set to 1/0 or 0/1 to control the voltage polarity and analogWrite to the enable pin to control the voltage (PWM).

Hello Gciurpita,

Would it be something like this ?

pinMode(pin1, OUTPUT)
pinMode(pin2, OUTPUT)
pinMode(pin3, OUTPUT)

in the set up.

digitalWrite(pin1, LOW)
digitalWrite(pin2, HIGH)
analogWrite(pin3, 255)

in the loop.

and just a matter of finding the right pins to activate ?
This shield is usually used with the <AFMotor.h> library which is hiding me the pins to activate. I probably can find this information somewhere.

The ancient, terribly inefficient L293D driver is rated at 600 mA/channel. You will have to parallel two channels to activate your solenoid.

Also plan on 2 to 4 V internal voltage drop with the L293D, so the solenoid power supply must be 6-8V.

Pololu has a great collection of modern, efficient motor drivers, at very reasonable prices, and they support their products.

jremington:
The ancient, terribly inefficient L293D driver is rated at 600 mA/channel. You will have to parallel two channels to activate your solenoid.

Also plan on 2 to 4 V internal voltage drop with the L293D, so the solenoid power supply must be 6-8V.

Pololu has a great collection of modern, efficient motor drivers, at very reasonable prices, and they support their products.

600 mA per channel but 1.2 A peak. I assume by your answer that the way I want to use the board does not fall into "peak" cartegory. Correct ?

I did not know this board was so bad. :frowning: I thought the voltage drop was fine because I was measuring 4.3 V on the motor pins when not connected to the solenoid but I assume by your answer that this changes when connected to the solenoid. Correct ?

Shall I try 6-8 V power supply on 2 channels ? No risk of burning everything ?

I also have this motor shield. I did not use because it can only power 2 DC motors which is not enough for my project. But I can use it to test the solenoid control since it's rated for 2 Amps.

Thanks.

3x correct.

The L298 is essentially the same, antique chip as the L293, but rated for slightly higher current. One channel might provide the solenoid with 1.1 A continuous, although I expect it to overheat and shut down after a while.

since it's rated for 2 Amps.

Peak, not continuous. All those 40 year old chips are overrated by the sellers.

Do yourself a favor, discover the modern world, and buy one of these motor drivers from Pololu. All of them are much better than what you have now.

OK thanks. I will buy one of these new shields in the future. I guess it will make my life easier.

Meanwhile I will try with 2 channels or with my other shield just to play test the concept.

There is just one thing that gets me confused is that the other project I was originally trying to copy (see my original post) had one arduino board with L293d shield driving eight 1 Amp solenoids. It seems to be working fine but I guess it is out of specs then...

one arduino board with L293d shield driving eight 1 Amp solenoids. It seems to be working fine

Feel free to doubt much of what is posted on the internet.