Go Down

Topic: Beta testers wanted for TinyServo library (Read 15950 times) previous topic - next topic

tylernt

Nov 11, 2013, 05:24 am Last Edit: Mar 05, 2014, 04:10 am by tylernt Reason: 1
After making my Hexapod robot, I decided to go whole hog and make a servo library for ATTiny 84, 85, and 2313 using the http://code.google.com/p/arduino-tiny/ Core.

I tested it on my ATtiny 84 and 85, but I just have a cheap analog micro servo so it would be good to get more testers. Also I don't have a 2313 so it would be nice to see if it works there too.

The library consumes roughly 750 bytes of flash and (I think) 10 bytes of RAM. This is nearly half the flash required by SoftwareServo, and unlike SoftwareServo, needs no (indeed, has no) refresh() function in loop().

On ATTiny85, you can run at 8MHz or 16MHz, but for 8MHz it's recommended (but not required) that you edit /hardware/arduino/cores/tiny/core_build_options.h and move the Core to Timer0.

Disclaimer: Servo damage may occur! The library will send 600uS to 2400uS pulses which may be beyond the physical reach of some servos, so use with care.

Attached below.

terryking228

Hi,
Thanks for your work on this. I will try to get a ATTINY going to try this. I usually am doing all 328 stuff.

OT somewhat: Since you are understanding Timers better than most, please see:
http://forum.arduino.cc/index.php?topic=199930.0 

Thanks!
Regards, Terry King terry@yourduino.com  - Check great prices, devices and Arduino-related boards at http://YourDuino.com
HOW-TO: http://ArduinoInfo.Info

Erni

#2
Nov 25, 2013, 03:00 pm Last Edit: Nov 25, 2013, 05:32 pm by Erni Reason: 1
Thanks for sharing
I just tried on ATtiny2313

I had to change
TIMSK1
In line 37 in to
TIMSK

and in line 71
TIM1_COMPA_vect
should be
TIMER1_COMPA_vect

After these changes it works (ATtiny2313 @8MHZ, no changes to the core timer setting)

I used both cheap analog and digital servo (TowerPro MG16r)

It seems that the speed is fasterv than when used on a ATtiny85, maybe the prescaler settings ?

tylernt

Thanks Erni! The zip attached to the first post of this thread has been updated to reflect your changes.

norlander

When trying to compile the example (using Arduino IDE 1.0.5) with ATtiny85 @ 8Mhz setting I get errors:

In file included from TinyServo.cpp:7:
/TinyServo.h:77:4: error: #error TinyServo library does not support this processor.
TinyServo.cpp: In function 'void moveServo(byte, byte)':
TinyServo.cpp:25: error: 'SERVOMAX' was not declared in this scope
TinyServo.cpp: In function 'void setupServos()':
TinyServo.cpp:64: error: 'OCRxA' was not declared in this scope
TinyServo.cpp: At global scope:
TinyServo.cpp:97: error: expected unqualified-id before 'if'
TinyServo.cpp:104: error: expected unqualified-id before 'else'

From the pre-processor DEFINE statements, it is obvious you were targeting to support ATtiny85 chips.   I am not an expert on pre-processor statements, but am thinking I need to predefine some statement.  Can someone help me resolve these errors?

I had the .h/.cpp files in same folder as the example sketch.  I did not modify any of the files. 

Thank you Krist

Erni

Quote
I had the .h/.cpp files in same folder as the example sketch.


They should be in the TinyServo folder

norlander

I have tried having the files in the TinyServo folder under Libraries [..\Arduino\libraries\TinyServo].  Compiling the Example in the examples folder [..\Arduino\libraries\TinyServo\examples\TinyServoExample\TinyServoExample.ino] still did not compile. Get same compiler error.

In file included from TinyServoExample.ino:39:
C:\Users\Krist\Documents\Arduino\libraries\TinyServo/TinyServo.h:77:4: error: #error TinyServo library does not support this processor.
TinyServoExample.ino: In function 'void loop()':
TinyServoExample:97: error: 'SERVOMAX' was not declared in this scope

Not sure why.  I have used other user built libraries and examples without trouble.  I am not seeing anything obvious in the code, and obviously others have the library working. 

tylernt

norlander,

What Core are you using, and what boards.txt entry are you selecting? I use these:

http://code.google.com/p/arduino-tiny/

Code: [Select]

##############################################################

attiny85at8.name=ATtiny85 @ 8 MHz (internal oscillator; BOD disabled)

# The following do NOT work...
# attiny85at8.upload.using=avrispv2
# attiny85at8.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny85at8.upload.using=arduino:arduinoisp
# attiny85at8.upload.protocol=avrispv2
# attiny85at8.upload.using=pololu

attiny85at8.upload.maximum_size=8192

# Default clock (slowly rising power; long delay to clock; 8 MHz internal)
# Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value
# Brown-out detection disabled; [BODLEVEL=111]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]

attiny85at8.bootloader.low_fuses=0xE2
attiny85at8.bootloader.high_fuses=0xD7
attiny85at8.bootloader.extended_fuses=0xFF
attiny85at8.bootloader.path=empty
attiny85at8.bootloader.file=empty85at8.hex

attiny85at8.build.mcu=attiny85
attiny85at8.build.f_cpu=8000000L
attiny85at8.build.core=tiny

###########################################################################

attiny85at16p.name=ATtiny85 @ 16 MHz (internal PLL; 4.3 V BOD)

# The following do NOT work...
# attiny85at16p.upload.using=avrispv2
# attiny85at16p.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny85at16p.upload.using=arduino:arduinoisp
# attiny85at16p.upload.protocol=avrispv2
# attiny85at16p.upload.using=pololu

attiny85at16p.upload.maximum_size=8192

# PLL Clock; Start-up time PWRDWN/RESET: 1K CK/14 CK + 4 ms; [CKSEL=0001 SUT=00]
# Brown-out detection level at VCC=4.3 V; [BODLEVEL=100]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]
# Serial program downloading (SPI) enabled; [SPIEN=0]

attiny85at16p.bootloader.low_fuses=0xC1
attiny85at16p.bootloader.high_fuses=0xD4
attiny85at16p.bootloader.extended_fuses=0xFF
attiny85at16p.bootloader.path=empty
attiny85at16p.bootloader.file=empty85at16.hex

attiny85at16p.build.mcu=attiny85
attiny85at16p.build.f_cpu=16000000L
attiny85at16p.build.core=tiny

norlander

thank you...let me try this.  I was using cores I got from http://hlt.media.mit.edu/?p=1229.  Had boards.txt that included the below...I used "attiny85-8.name=ATtiny85 (internal 8 MHz clock)".  I will try using this other hardware core you suggest.  I am assuming I just load those files into the "Hardware" folder like I did for the other cores.


attiny85.name=ATtiny85 (internal 1 MHz clock)
attiny85.bootloader.low_fuses=0x62
attiny85.bootloader.high_fuses=0xdf
attiny85.bootloader.extended_fuses=0xff
attiny85.upload.maximum_size=8192
attiny85.build.mcu=attiny85
attiny85.build.f_cpu=1000000L
attiny85.build.core=arduino:arduino
attiny85.build.variant=tiny8

attiny85-8.name=ATtiny85 (internal 8 MHz clock)
attiny85-8.bootloader.low_fuses=0xe2
attiny85-8.bootloader.high_fuses=0xdf
attiny85-8.bootloader.extended_fuses=0xff
attiny85-8.upload.maximum_size=8192
attiny85-8.build.mcu=attiny85
attiny85-8.build.f_cpu=8000000L
attiny85-8.build.core=arduino:arduino
attiny85-8.build.variant=tiny8

attiny85-20.name=ATtiny85 (external 20 MHz clock)
attiny85-20.bootloader.low_fuses=0xfe
attiny85-20.bootloader.high_fuses=0xdf
attiny85-20.bootloader.extended_fuses=0xff
attiny85-20.upload.maximum_size=8192
attiny85-20.build.mcu=attiny85
attiny85-20.build.f_cpu=20000000L
attiny85-20.build.core=arduino:arduino
attiny85-20.build.variant=tiny8


norlander

perfect feedback...thank you.  I used new core files for Arduino 1.0, put them in Hardware folder, and changed the "Prospective Boards.txt" file to just "boards.txt".  Servo is running as expected with example code!   Thank you very much!

The servo performance is better [smoother] than the library I was using before.

I will play with this library more and provide whatever feedback I can.


again, thank you.
Krist

norlander

question before I get into my beta testing.  For power conservation reasons, I am going to putting my ATtiny85 into extended sleep modes.  I will be putting into the cyclic sleep using the watchdog timer [setup_watchdog(WDTO_8S)] and repeatedly wake/sleep for a specified number of cycles and then enabling servo commands (along with some other activity).  Are you already aware of issues that may arise from using your library under these conditions because of how you are using the timers? 

If I run into any anomalies, I will share them in this forum.

tylernt

Well glad you got it working. I'm not familiar with the HLT core but I assume the constants for CPU definition are different or don't exist.

As for sleeping, I haven't tested that but I since interrupts are disabled when sleeping, one of the servo pins would get left in a HIGH state when sleeping which may send the servo to the extreme end of travel. To sleep safely, I would recommend something like the following sequence. Whether you need to disable/enable Timer0 or Timer1 depends on if you have moved millis(). The below example assumes TinyServo is using Timer1, substitute OCIE0A for OCIE1A if TinyServo is using Timer0.

Code: [Select]

TIMSK &= ~(1 << OCIE1A); // Disable Timer/Counter1 Output Compare Match A Interrupt, preserving other bits
digitalWrite(servoPin[currentServo], LOW);
// sleep here
TIMSK |= (1 << OCIE1A); // Timer/Counter1 Output Compare Match A Interrupt Enable, preserving other bits


I'm not certain this will work but it's a good place to start. I suppose I should upgrade the library to add a "detach servo" function for situations like this. So, thanks for the feedback, you found a use case I missed. :)

quixote_arg

I tried it and with ATtiny2313 @ 8 MHz, with the following boards.txt code

Code: [Select]

attiny2313at8.name=ATtiny2313 @ 8 MHz

# The following do NOT work...
# attiny2313at8.upload.using=avrispv2
# attiny2313at8.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny2313at8.upload.using=arduino:arduinoisp
# attiny2313at8.upload.protocol=avrispv2
# attiny2313at8.upload.using=pololu

attiny2313at8.upload.maximum_size=2048

# Default clock (slowly rising power; long delay to clock; 8 MHz internal)
# Int. RC Osc. 8 MHz; Start-up time: 14 CK + 65 ms; [CKSEL=0100 SUT=10]; default value
# Brown-out detection disabled; [BODLEVEL=111]
# Serial program downloading (SPI) enabled; [SPIEN=0]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]

attiny2313at8.bootloader.low_fuses=0xE4
attiny2313at8.bootloader.high_fuses=0x9F
attiny2313at8.bootloader.extended_fuses=0xFF
attiny2313at8.bootloader.path=empty
attiny2313at8.bootloader.file=empty2313at8.hex

attiny2313at8.build.mcu=attiny2313
attiny2313at8.build.f_cpu=8000000L
attiny2313at8.build.core=tiny


the example code compiles ok (haven't tested it on the core itself)
but if I select ATtiny2313 @ 1 MHz (with this code):

Code: [Select]

attiny2313at1.name=ATtiny2313 @ 1 MHz

# The following do NOT work...
# attiny2313at1.upload.using=avrispv2
# attiny2313at1.upload.using=Pololu USB AVR Programmer

# The following DO work (pick one)...
attiny2313at1.upload.using=arduino:arduinoisp
# attiny2313at1.upload.protocol=avrispv2
# attiny2313at1.upload.using=pololu

attiny2313at1.upload.maximum_size=2048

# Default clock (slowly rising power; long delay to clock; 8 MHz internal; divide clock by 8)
# Int. RC Osc. 8 MHz; Start-up time: 14 CK + 65 ms; [CKSEL=0100 SUT=10]; default value
# Divide clock by 8 internally; [CKDIV8=0]
# Brown-out detection disabled; [BODLEVEL=111]
# Serial program downloading (SPI) enabled; [SPIEN=0]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]

attiny2313at1.bootloader.low_fuses=0x64
attiny2313at1.bootloader.high_fuses=0x9F
attiny2313at1.bootloader.extended_fuses=0xFF
attiny2313at1.bootloader.path=empty
attiny2313at1.bootloader.file=empty2313at1.hex

attiny2313at1.build.mcu=attiny2313
attiny2313at1.build.f_cpu=1000000L
attiny2313at1.build.core=tiny


then it fails to compile with:

Code: [Select]

In file included from TinyServoExample.ino:39:0:
~/sketchbook/libraries/TinyServo/TinyServo.h:26:6: error: #error TinyServo does not support this CPU clock speed
     #error TinyServo does not support this CPU clock speed
      ^
TinyServoExample.ino: In function 'void loop()':
TinyServoExample.ino:97:23: error: 'SERVOMAX' was not declared in this scope

tylernt

Hi quixote_arg,

Thanks for trying it out. I'm afraid that the library does not support 1MHz. If I ever get around to updating the library to include a 'detach' function, I will see about supporting 1MHz clock speeds as well.

In the meantime, you should be able to tweak it to work at 1MHz though. In the ATtinyX313 section of setupServos() in the .cpp, change the Timer1 prescaler from 64 to 8 by removing the CS10 bit:

Code: [Select]

TCCR1B |= (1 << CS11); // prescale of 8, preserving existing bits


Then edit the .h file and in the ATtinyX313 section change the #if from 8000000 to 1000000. I think that will do the trick.

quixote_arg

thanks for the quick reply

I was under the false assumption that in order to run a tiny2313@8MHz I needed an external crystal, which isn't the case, so I can run the code fine @8MHz

Go Up