-1
\$\begingroup\$

Here what I am trying to do is control servo motor with a pottentiometer and record its movement using analog to digital converter and than play. I started with just moving the servo. To see which angle is the servo on, I print the angle calculation to lcd screen. I do this with this code and it works fine:

void servo(unsigned long int b,c)
{
output_high(pin_d0);
delay_us(550+b);  
output_low(pin_d0);
delay_us(19450-b);  
printf(lcd_putc,"\fVal = %u DEGREE",c);
}
int n=0;
int a=0;
while(1)
      {

                    i=read_adc();
                    degree=i*2/11.1;
                    i=i*2;
                    servo(i,degree);
      }

but problem starts when i try to record and play the movement. Here what I did when first button pressed record movements and when second button pressed play the record.

            while(1)
      {
                while(input(pin_a1)){ //while button 1 pressed record
                    i=read_adc();
                    degree=i*2/11.1;
                    i=i*2;
                    servo(i,degree);
                    write_eeprom(n,i);
                    n++;
          delay_ms(1000);
          if(input(pin_a2)) //if button 2 pressed go to play
          delay_ms(50);
          break;
                }
          while(input(pin_a2)){ //play eeprom


          i=read_eeprom(a);
          degree=i*2/11.1;
          servo(i,degree);
          delay_ms(1000);
          a++;
          if(a==10)
          a=0;
          }



  }

First I press and hold first button to record values and I record 10 values with a delay of 1000ms and lcd screen shows the right angles. but after I press and hold second button servo is not moving just lcd is active. and LCD shows wrong angles. For example I record 160 , 50 , 45,... it plays 20,7,10... I couldn't find any mistake. If anybody can help I will be appreciated. Thanks for reading.

Here my real code is

    #include <16f877.h>
    #device adc=10

  #FUSES XT
  #FUSES NOWDT                  
  #FUSES NOPUT                  
  #FUSES NOPROTECT              
  #FUSES NODEBUG                
  #FUSES NOBROWNOUT             
  #FUSES NOLVP                  
 #FUSES NOCPD                 
  #FUSES NOWRT                  



  #define use_portb_lcd TRUE
  #use delay (clock=4000000)
  #include <lcd.c>


  unsigned long int i=0,degree=0;

  int n=0;
  int a=0;



  void servo(unsigned long int b,c)
  {
  output_high(pin_d0);
  delay_us(550+b);  
  output_low(pin_d0);
  delay_us(19450-b);  
  printf(lcd_putc,"\fVal = %u DEGREE",c);



  }

   void main()
  { 

  set_tris_a(0x01);
  set_tris_d(0x00);
  output_d(0x00);
  output_b(0x00);
  setup_adc(adc_clock_div_32);
  setup_adc_ports(AN0);
  set_adc_channel(0);
  lcd_init();

      while(1)
      {
                while(input(pin_a1)){
                    i=read_adc();
                    degree=i*2/11.1;
                    i=i*2;
                    servo(i,degree);
                    write_eeprom(n,i);
                    n++;
          delay_ms(1000);
          if(input(pin_a2))
          delay_ms(50);
          break;
                }
          while(input(pin_a2)){


          i=read_eeprom(a);
          degree=i*2/11.1;
          servo(i,degree);
          delay_ms(1000);
          a++;
          if(a==10)
          a=0;
          }



  }
  }

PROBLEM SOLVED I have been trying to write on eeprom values more then 8bit(256) which is "i".

\$\endgroup\$
  • \$\begingroup\$ Have any ideas? \$\endgroup\$ – Anıl Kırıkkaya Apr 27 '18 at 8:35
0
\$\begingroup\$

Given that you never initialize either n (when writing) or a (when reading), there's really no way to know where in the EEPROM you're working, or whether you're writing and reading the same set of addresses.

Try displaying the write/read address on the LCD along with the data.

\$\endgroup\$
  • \$\begingroup\$ sorry I forgot to add a and n they are 0 initially \$\endgroup\$ – Anıl Kırıkkaya Apr 25 '18 at 12:07
  • 1
    \$\begingroup\$ You need to show us the actual code you're running, not some paraphrase of it. Reduce it to the minimum set that actually demonstrates the problem. In any case, my suggestion is still valid. \$\endgroup\$ – Dave Tweed Apr 25 '18 at 12:11
  • \$\begingroup\$ I didn't understand. In first while loop I write i to n memory address by the code write_eeprom(n,i). In this case first, it writes i to 0 address after 1000ms it writes to i to 1 address and so on. It reads the same numbers in second while loop. \$\endgroup\$ – Anıl Kırıkkaya Apr 25 '18 at 12:36
0
\$\begingroup\$

Looks like you're passing servo a float, and it wants a long int. If this isn't the case, please post the real code.

\$\endgroup\$
  • \$\begingroup\$ I posted the real code. iis an integer so I don't think that I pass servo a float. Am I wrong? I am new at programming. \$\endgroup\$ – Anıl Kırıkkaya Apr 25 '18 at 14:25
  • \$\begingroup\$ @AnılKırıkkaya servo(i,degree); is in your code. Degree is a float, and the second argument of servo is a long integer. Since the second argument is what the LCD displays, and it is displaying incorrectly, this is likely at least one of your issues. \$\endgroup\$ – Scott Seidman Apr 25 '18 at 14:38
  • \$\begingroup\$ Oops, found the declaration of degree, and it is a long int. there may be casting issues, though. Try degree=(long int)(i*2/11.1); \$\endgroup\$ – Scott Seidman Apr 25 '18 at 14:42
  • \$\begingroup\$ Note that you'll lose your fractional part, and suffer from quantization, even if the casting happens as expensive. What do you think happens, for example, if i<5?? Then, degree=0!! \$\endgroup\$ – Scott Seidman Apr 25 '18 at 14:46
  • \$\begingroup\$ Here my problem is with the second while part. In first while part everything works well servo rotating lcd working nice int float or long int is not seems to be issue. But in second loop lcd working but with wrong degrees and servo is not working at all. Sorry I kept you bussy. \$\endgroup\$ – Anıl Kırıkkaya Apr 25 '18 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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