We all love servos, we love them with breakfast, lunch and dinner. But one serious concern that arises is when we include other noisy components and interference gets in the way. This problem is compounded to extreme when you introduce distance. The further you get from the PWM source the greater the signal is degraded and higher possibility that noise will be introduced into your signal. Noise can cause erratic behavior, in-accurate positioning, and lose of hair. But, this doesn't have to be. I have the solution and you're going to love it. Light.
Servos
How servos work is based on 2 things. Frame time and time the line is high versus low. The frame below is 20ms. That means that the beginning to end of our timer that is creating the PWM signal has a period of 20ms. When the PWM signal is on for 1500us, our servo moves to the central position. To move the servo 90 degrees clockwise, a pulse of 2000us is required and so on.
With noise your signal looks like:
So.... what position is that?
This problem is magnified by very large factors when distance is involved. Not only does the signal degrade in amplitude, but with the added noise it becomes almost impossible to rely on this type of configuration. The best solution is transfer by light.
Fiber Optics
When using fiber optics, light is impervious to large current consuming motors that will flood your PWM signal with noise. Also, light doesn't degrade over short or even fairly large distances. You could have your servo 30 meters away and it is like it is directly connected. But the first thought when thinking about communication over light is: Complex ( it's really not )
The fiber optic click is one of those overlooked magic tools. Look closely at the silk screened section "GPIO UART". What does this mean? If you look at the upper right pin, you will see a label "PWM".
This means, you can send light pulses by standard method of UART TX, or the magic trick...... PWM. Changing the resistor from UART to GPIO allows you to now use those beautiful PWM pulses through the Fiber Optic click TX line. Where this is received is through the receiver port and then relayed through the RX pin of the MikroBus. Connecting the servo to this pin would give you 100's of meters of control, with perfect positioning.
Code Example
Coding this connection couldn't be easier. Here is an example of using the Fiber Opt click over UART, additional information about the example can be found on Libstock.
// LCD module connections sbit LCD_RS at LATB4_bit; sbit LCD_EN at LATB5_bit; sbit LCD_D4 at LATB0_bit; sbit LCD_D5 at LATB1_bit; sbit LCD_D6 at LATB2_bit; sbit LCD_D7 at LATB3_bit; sbit LCD_RS_Direction at TRISB4_bit; sbit LCD_EN_Direction at TRISB5_bit; sbit LCD_D4_Direction at TRISB0_bit; sbit LCD_D5_Direction at TRISB1_bit; sbit LCD_D6_Direction at TRISB2_bit; sbit LCD_D7_Direction at TRISB3_bit; // End LCD module connections unsigned short cmd_buf = 0; // Control byte void main() { ANSELB = 0; // Configure PORTB pins as digital ANSELC = 0; // Configure PORTC pins as digital ANSELD = 0; // Configure PORTD pins as digital TRISD = 0xFF; // Configure PORTD as input Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1, 1, "Fiber Opt click"); // Write text in first row Lcd_Out(2, 1, "Press RDx button"); // Write text in first row UART1_Init(19200); // Initialize UART module at 19200 bps Delay_ms(100); // Wait for UART module to stabilize RC1IE_bit = 1; // turn ON interrupt on UART1 receive RC1IF_bit = 0; // Clear interrupt flag PEIE_bit = 1; // Enable peripheral interrupts GIE_bit = 1; // Enable GLOBAL interrupts while(1) { switch(PORTD) // Check which PORTRD button is pressed { case 0x01: UART1_Write(1); // Send command for RD0 press break; case 0x02: UART1_Write(2); // Send command for RD1 press break; case 0x04: UART1_Write(3); // Send command for RD2 press break; case 0x08: UART1_Write(4); // Send command for RD3 press break; case 0x10: UART1_Write(5); // Send command for RD4 press break; case 0x20: UART1_Write(6); // Send command for RD5 press break; case 0x40: UART1_Write(7); // Send command for RD6 press break; case 0x80: UART1_Write(8); // Send command for RD7 press break; } if(cmd_buf) // If command is received { Lcd_Out(2,1, "RD is pressed "); Lcd_Chr(2,3, cmd_buf + 47); // Indicate which button is pressed cmd_buf = 0; // Clear the command value Delay_ms(333); // Take five :) } } } void interrupt() // Interrupt routine { if(RC1IF_bit == 1) // Checks for Receive Interrupt Flag bit cmd_buf = UART_Read(); // Storing button press command }
Other Uses of Fiber Optics
Ever thought about sending a analog signal over fiber? You can. PWM is often used for simulated analog values. You could send those analog values large distances.
What about speed? How fast do you want to go? Light is pretty fast, you can drive the light as fast as your little MCU can go and guess what.... it's still not as fast as light. So put the pedal to the metal and the Fiber Opt click won't break a sweat. The great thing about it, you won't get noise.