dmadison / ServoInput

Interrupt-driven servo decoder library for Arduino
GNU Lesser General Public License v3.0
22 stars 10 forks source link

Support for Digispartk ATTiny 85 board #16

Closed bmanfoui closed 3 years ago

bmanfoui commented 3 years ago

Hi , this is a great library. Would it be possible to add support for the DigiSpark Attiny85 board? That would be great.

Thanks for your efforts

dmadison commented 3 years ago

Hmm. It looks like the ATtiny85 only has one interrupt capable pin and it's unfortunately not well supported in Arduino. The relevant boards packages would need to be modified to add the Arduino-compliant interrupt functionality. There's nothing I can do about that on my end.

That being said, the library should still work using pin change interrupts if you explicitly disable the interrupt support using the SERVOINPUT_NO_INTERRUPTS define before the header file is included. I believe NicoHood's PCINT library works on the ATtiny chips so you shouldn't have to configure the registers yourself. Look at the 'PinChangeLib' example for reference. Your setup should look something like this:

#define SERVOINPUT_NO_INTERRUPTS
#include <PinChangeInterrupt.h>
#include <ServoInput.h>

ServoInputPin<5> servo;

That compiles on my end but unfortunately I don't have a DigiSpark board to test with. Let me know if there are any issues.

bmanfoui commented 3 years ago

Hey Thanks for the response

I’m new to this so I’m still learning the ropes. I’m just looking for a smaller board than the Uno that I can use as a light controller on my RC crawler scale trucks that I build.

I think a nano would fit so I may try that board

Thanks again

Bryan

Sent from Mail for Windows 10

From: Dave Madison Sent: March 23, 2021 7:07 PM To: dmadison/ServoInput Cc: bmanfoui; Author Subject: Re: [dmadison/ServoInput] Support for Digispartk ATTiny 85 board(#16)

Hmm. It looks like the ATtiny85 only has one interrupt capable pin and it's unfortunately not well supported in Arduino. The relevant boards packages would need to be modified to add the Arduino-compliant interrupt functionality. There's nothing I can do about that on my end. That being said, the library should still work using pin change interrupts if you explicitly disable the interrupt support using the SERVOINPUT_NO_INTERRUPTS define before the header file is included. I believe NicoHood's PCINT library works on the ATtiny chips so you shouldn't have to configure the registers yourself. Look at the 'PinChangeLib' example for reference. Your setup should look something like this:

define SERVOINPUT_NO_INTERRUPTS

include

include

ServoInputPin<5> servo; That compiles on my end but unfortunately I don't have a DigiSpark board to test with. Let me know if there are any issues. — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

dmadison commented 3 years ago

Look into the Pro Micro. A little bit smaller than the Nano and has 5 external interrupt pins compared to the Nano's 2.

dmadison commented 3 years ago

I'm assuming this is solved. Feel free to re-open if you intend to use the ATtiny.

bmanfoui commented 3 years ago

Hey thanks for the input I’ll check out the pro micro

JamoDevNich commented 8 months ago

Funny enough, I was looking at using the Attiny85 for exactly this - controller for a lighting setup on my RC.

I got this library somewhat working on my Digispark, however I think the poor board support is either partly related to the compiler being used for the Attiny85 in the PlatformIO IDE, or the abandoned Digispark arduino framework.

First - the changes I used to get this working - the following at the top of the code prior to including the libraries:

#include <Arduino.h>

#ifdef ARDUINO_AVR_DIGISPARK 
  int digitalPinToInterrupt(int pin) { return -1; }
#endif

#include <PinChangeInterrupt.h>
#include <ServoInput.h>
#include <AsyncDelay.h>

Apparently the function digitalPinToInterrupt isn't defined by the Digispark arduino framework for some reason.

Other change was a hack in the ServoInput lib to satisfy the compiler - I'm a bit out of my depth here, so unsure further implications of this change from the following:

https://github.com/dmadison/ServoInput/blob/79bd516bd76022b315d074bc2e5bedd4e7c3d057/src/ServoInput.h#L106-L110

to the following:

    void attachInterrupt() {
        #if !defined(SERVOINPUT_NO_INTERRUPTS)
            #if !defined(SERVOINPUT_SUPPRESS_WARNINGS) && !defined(SERVOINPUT_USING_PCINTLIB)
                #define NOT_AN_INTERRUPT -1
                static_assert(digitalPinToInterrupt(Pin) != NOT_AN_INTERRUPT, "This pin does not support external interrupts!");
            #endif

Works somewhat with two servo signals, however the pulse durations can be a bit unstable (expected here as I'm not using hardware interrupts), occasionally returning values completely opposite from what is being set, for example at a pulse duration of 1200, it may return 1200 before jumping up to 1800 and then back down to 1200.

Running identical code on an Arduino Uno board (without the hack mentioned above, and compiled in the Arduino IDE instead) with one servo signal on an external interrupt and the other on a PCINT simultaneously is much more stable, the pulse durations in that setup could probably be considered within a margin of error.


Alternate unsuccessful attempts

I did try some other things prior to this, such as having the digitalPinToInterrupt function return the only hardware supported interrupt pin

#ifdef ARDUINO_AVR_DIGISPARK 
  int digitalPinToInterrupt(int pin) { return pin==2 ? 2 : -1; }
#endif

This compiles and flashes to the digispark just fine, but does not return any values from the servo. Sadly don't have a debugger to look further into what's happened there...

The definitions #define SERVOINPUT_NO_INTERRUPTS and #define SERVOINPUT_USING_PCINTLIB unfortunately don't work standalone here because of the missing digitalPinToInterrupt function in the framework.

Something that seems feasible for others who run into this issue could be outright replacing the abandoned Digispark arduino framework with a newer one called ATTinyCore, found some instructions in one of their issues](https://github.com/SpenceKonde/ATTinyCore/issues/124#issuecomment-297477955) on how to get it added into PlatformIO IDE.

Personally though I think I'm just going to look for a different board to use, the suggested Pro Micro looks like an ideal replacement with 5 external interrupts

dmadison commented 8 months ago

Thanks for the feedback @JamoDevNich!

Have you tried using the SERVOINPUT_NO_INTERRUPTS flag? It needs to be defined before the header file is #include'd, but should work to ignore the lack of the digitalPinToInterrupt function. With that set I don't believe the library needs any changes to work, although of course the pin needs to be polled which introduces issues as you've discovered.

ETA: Apologies, it's been too long since I've looked at this code. Yes, I think your modifications and your usability notes are on point. I think defining NOT_AN_INTERRUPT at the top of the header is probably a good change in general, and I should probably push an update to that effect.

dmadison commented 7 months ago

The latest release, version 2.0.0, includes a change that should fix the NOT_AN_INTERRUPT issue. Unfortunately there's nothing I can do about the digitalPinToInterrupt() issue from the ATtiny85 core, as that's not something that can be checked at compile-time.

If you're still interested in using the ATtiny85, I would suggest creating an issue in the ATtiny85 core about adding both of those features for compatibility reasons.