0

Using Servo.h it is possible to run a servo from just about any pin.....obviously the more pins the more servos...hence the question " how can I do this with a MCP23017 ? ". I have searched the web a fair bit but no luck. Is there a modified Servo library out there?? It's such an obvious solution i figure it must have been done before. Any suggestions..Thanks.

6 Answers 6

3

Using Servo.h it is possible to run a servo from just about any pin.....obviously the more pins the more servos...hence the question " how can I do this with a MCP23017?

The Servo library could be modified to allow toggling of GPIO pins on a MCP23017 but there are some issues with timing.

The library uses Timers and Interrupt Service Routines (ISR) to handle the pulse width. The servo pin is toggled in the ISR.

At 100 KHz (100 Kbps) I2C at least 3 bytes need to be transmitted to the MCP230017 to toggle a pin. That is approx. 300 us and not possible to do from the Servo ISR. Another execution pattern is required.

Cheers!

1
  • Thank All for the feedback...modifying a library is not an option at this time...not that good yet...The more research I do the less likely the option seems so I will cheat and purchase a 386 MEGA board...54 I/O's is sufficient for my needs on this project. 13 Servo (seperate power supply) and 28 repeater LED's ....track side LED's will be handled by MCP23017 x 2 in series. I was using the Adafruit 16 servo board but I think I fritz-ed it. Oh well thats life.
    – Doug
    Apr 4, 2017 at 9:25
2

Theoretically, yes. It would be pretty interesting to see, but running multiple servos would account for a huge amount of what you can reasonably do with your code and probably be a huge headache.

Perhaps a better solution would be to use a PWM expander like the PCA9685.

2

how can I do this with a MCP23017 ? ".

you can but it would be fairly expensive in processing power, as you need to keep track of both rising and falling edges of every channel at all times, and send the data to the chip -> may not be doable given i2c's speed limitations.

I have searched the web a fair bit but no luck.

I wrote a variety of approaches / implementations on driving multiple servo channels off of one timer, with or without output compare, here: https://dannyelectronics.wordpress.com/2017/02/18/driving-multiple-servos-off-a-pic-timer2-ranged-extended/

it will branch out to a few other variants, depending on resources available to you.

2

For PWM, the MCP23017 would have to be software-driven. I would suggest one of the PCA9685 boards, which give you hardware PWM (and can also provide digital pins). These are a bit more expensive, but very easy to use, and are driven by I2C in the same way.

1
  • Indeed, the PCA9685 is used to control servos, I also use them to dim lights with an array of mosfet switches !
    – Damien
    Jul 8, 2023 at 18:21
1

For example...

unsigned long long servo_timing[2]={0,0};
int A_data=0;
void servo_ini()
{
  Wire.beginTransmission(0x20);
    Wire.write(0x00);      // address bank A
    Wire.write(0x00);
    Wire.endTransmission();
}
void servo_set(unsigned int servo_tim,bool servo_mod){
   if(servo_mod==1){
    servo_tim=map(servo_tim,0,180,200,1900);
   }
   //if(servo_vector<=0)/*lcd_tim=650;*/servo_tim=220;/0
   //if(servo_vector==1)/*lcd_tim=1400;*/servo_tim=1000;/90
   //if(servo_vector>=2)/*lcd_tim=2255;*/servo_tim=1870;/180
   if(micros()-servo_timing[0]>servo_tim)
   {
     A_data&=0b11111110;
     Wire.beginTransmission(0x20);
     Wire.write(0x12);      // address bank A
     Wire.write(A_data);
     Wire.endTransmission();
     if(micros()-servo_timing[1]>(20000-servo_tim))
     {
       A_data|=0b00000001;
       Wire.beginTransmission(0x20);
       Wire.write(0x12);      // address bank A
       Wire.write(A_data);
       Wire.endTransmission();
       servo_timing[0]=micros();
       servo_timing[1]=micros();
     }

  }
}
1

I succeeded in pwm (servo control) with mcp23017. Moreover, it is 16ch. The mcp23017 in the Arduino Library also has a wordwrite write, but the frequency still couldn't catch up. There is no choice but to create a library by yourself and generate a pulse of 0.5msec .. 2.5msec in 20msec 50Hz to drive the servo motor. We are currently organizing the library thank you https://twitter.com/chrmlinux03/status/1534834169737789441?s=20&t=EqkVXJ2v1H3i_tfZsXfjHQ

https://github.com/chrmlinux/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.