ATTINY85 OneWireArduinoSlave #1

Open
opened 5 years ago by IanF · 25 comments
IanF commented 5 years ago

This library has been very well thought out and works well on the Arduino UNO. It is the only Arduino OneWire slave library I have found which is entirely interrupt driven and capable of correctly reading data sent following OneWire commands. Thank you.

I have written a FakeDS2413 sketch for an Arduino UNO which uses pretty much the full library capability and works just as the physical DS2413 works. I am happy to contribute this example if it would be helpful.

My issue regards porting the FakeDS2413 and OneWire Slave library to an ATTINY85. As far as I can see, the porting requires adaptation of the interrupts on the one wire port and the timer1 interrupts to suit the ATTINY85. Tuning of the timing will also be required.

To this point I have not been able to get the interrupt processing working. So far I have:

  • written a self contained sketch for the ATTINY85 which shows the method you have used to set up the interrupt port, redirect the vector etc all works as it should. The interrupt restrictions on the ATTINY85 means the onewire port has to be PB2 (pin 7) if you want rising/falling/change/low/high interrupt handling (ie INT0).

  • modified your lowlevel.h file to adapt the register handling to the ATTINY85. Only fairly minor changes are needed AFAICS.

  • modified the timer registers to match the ATTINY85. Again I have written self contained sketches to demonstrate the settings are correct. So far no tuning of timing has been done.

And here comes the BUT.

After many hours a testing/debugging the library on the ATTINY I have been unable to get even the onewire reset pulse to correctly process through "begin" "beginWaitReset_()" then "waitReset_" processing. I can also see on my oscilloscope it does not trigger.

For some reason it appears the ::attachInterrupt(…) in lowlevel.h is not doing what it should. I have no idea why, as the same api works ok in my self contained demo sketch.

By setting the correct ATTINY85 registers etc I can get the reset pulse to trigger to an test ISR INT0 vector I inserted. But using the attachInterrupt api does not work for me on the ATTINY85. (Obviously this same api works in the UNO ATMEGA328 version no problem)

I would appreciate any insight you can give as to why?? Basically I am stuck at this point.

This library has been very well thought out and works well on the Arduino UNO. It is the only Arduino OneWire slave library I have found which is entirely interrupt driven and capable of correctly reading data sent following OneWire commands. Thank you. I have written a FakeDS2413 sketch for an Arduino UNO which uses pretty much the full library capability and works just as the physical DS2413 works. I am happy to contribute this example if it would be helpful. My issue regards porting the FakeDS2413 and OneWire Slave library to an ATTINY85. As far as I can see, the porting requires adaptation of the interrupts on the one wire port and the timer1 interrupts to suit the ATTINY85. Tuning of the timing will also be required. To this point I have not been able to get the interrupt processing working. So far I have: - written a self contained sketch for the ATTINY85 which shows the method you have used to set up the interrupt port, redirect the vector etc all works as it should. The interrupt restrictions on the ATTINY85 means the onewire port has to be PB2 (pin 7) if you want rising/falling/change/low/high interrupt handling (ie INT0). - modified your lowlevel.h file to adapt the register handling to the ATTINY85. Only fairly minor changes are needed AFAICS. - modified the timer registers to match the ATTINY85. Again I have written self contained sketches to demonstrate the settings are correct. So far no tuning of timing has been done. And here comes the BUT. After many hours a testing/debugging the library on the ATTINY I have been unable to get even the onewire reset pulse to correctly process through "begin" "beginWaitReset_()" then "waitReset_" processing. I can also see on my oscilloscope it does not trigger. For some reason it appears the ::attachInterrupt(…) in lowlevel.h is not doing what it should. I have no idea why, as the same api works ok in my self contained demo sketch. By setting the correct ATTINY85 registers etc I can get the reset pulse to trigger to an test ISR INT0 vector I inserted. But using the attachInterrupt api does not work for me on the ATTINY85. (Obviously this same api works in the UNO ATMEGA328 version no problem) I would appreciate any insight you can give as to why?? Basically I am stuck at this point.
Owner

Hello,

you're not the first one to try to make it work on ATTINY85, but alas I don't have one (and don't need one at this time, nor have time to work on the library in the coming month), so I never tried myself. So I'm sorry I have no hints for you as to what would cause problems.

I think someone worked on this hardware, you may want to look if he got something working here: https://github.com/ntruchsess/OneWireArduinoSlave/tree/DS2890_attiny (I'm just hinted by the branch name, haven't looked at the code at all)

This commit in particular looks interesting (but again, haven't looked at the code): 446391ff8b

Let me know if it helps...

Hello, you're not the first one to try to make it work on ATTINY85, but alas I don't have one (and don't need one at this time, nor have time to work on the library in the coming month), so I never tried myself. So I'm sorry I have no hints for you as to what would cause problems. I think someone worked on this hardware, you may want to look if he got something working here: https://github.com/ntruchsess/OneWireArduinoSlave/tree/DS2890_attiny (I'm just hinted by the branch name, haven't looked at the code at all) This commit in particular looks interesting (but again, haven't looked at the code): https://github.com/ntruchsess/OneWireArduinoSlave/commit/446391ff8b6c20aabfb1327a51a971c3d1ef67d2 Let me know if it helps...
Poster

Hi,

Thanks for getting back to me so quickly.

I realised soon after posting what the interrupt issue was. The ATTINY85 timer works a little differently to the UNO and was triggering very early blocking the pin INT0 interrupts.

I have spent some time chasing the cause. Good news is I understand much more the details of the ATTINY85 interrupts.

I am not surprised others have tried to port to the ATTINY85 it is attractive as a platfrom to emulate many onewire devices.

Thanks for the DS2890 link, there may be further to learn there.

regards

Hi, Thanks for getting back to me so quickly. I realised soon after posting what the interrupt issue was. The ATTINY85 timer works a little differently to the UNO and was triggering very early blocking the pin INT0 interrupts. I have spent some time chasing the cause. Good news is I understand much more the details of the ATTINY85 interrupts. I am not surprised others have tried to port to the ATTINY85 it is attractive as a platfrom to emulate many onewire devices. Thanks for the DS2890 link, there may be further to learn there. regards
IanF closed this issue 5 years ago
IanF reopened this issue 5 years ago

Hello IanF, I have recently started using this library as well. It works very well so far and the code is excellent. I could use your FakeDS2413 for Arduino UNO, do you think you can do a pull request on this to commit your example on that?

Moreover, I will be very thankful if you can share more details on what you did to make your code work on the ATTiny85. I will be using that uC soon as a replacement for the UNO. By the way, are you using the ATTiny with the internal clock? Or are you using an external oscillator? At what frequency are you clocking it?

Regards.

Hello IanF, I have recently started using this library as well. It works very well so far and the code is excellent. I could use your FakeDS2413 for Arduino UNO, do you think you can do a pull request on this to commit your example on that? Moreover, I will be very thankful if you can share more details on what you did to make your code work on the ATTiny85. I will be using that uC soon as a replacement for the UNO. By the way, are you using the ATTiny with the internal clock? Or are you using an external oscillator? At what frequency are you clocking it? Regards.
Poster

Hi sebascarra

I am not able to create a pull request or attach a file here. I assume my settings as a new gitea user don't allow that??

I have made some progress on porting the code to the attiny85. It works, but not reliably as I have not tuned up the timings ( which are very critical).

To set up the attiny85 I have

  • set the internal clock to 16MHZ (fuses L 0xF1, H 0XDF, E 0XFF ). But external 16mhz may be better?

  • tuned the OSCCAL value to 16MHZ

  • Modded the low level interrupt handling - the onewire pin must be PB2 (pin 7) on the attiny85 as PB2 is the only pin which handles rising, falling, change interrupts. The attachInterrupt api works the same as on the UNO.

  • Created the register set up for the attiny85 8 bit timer. The attiny85 timer has some subtle differences to the UNO and does not have a 64 prescaler (highest is 32). This means the timer values can not be exactly like the UNO.

  • I am using my FakeDS2413 as a test because the internal processing uses most of the onewire slave capability.

  • The attiny85 FakeDS2413 compiles to about 4000 bytes of flash and < 100 bytes of ram. ie there is plenty of space.

Below are the attiny85 definitions I am currently using in lowlevel.h

Be aware - Tweaking the attiny85 timings is not easy. There are only very rudimentary debug facilities usable on the attiny85. Bit like trying to do brain surgery through an earhole!!

///////////////////////////////////////////

#if defined (AVR_ATtiny85)

#define CLEARINTERRUPT GIFR |= (1 << INTF0)
#define USERTIMER_COMPA_vect TIMER1_COMPA_vect

attribute((always_inline)) static inline void UserTimer_Init( void )
{
TCCR1 = 0; //stop the timer
TCNT1 = 0;
TIMSK = 0;// clear timer interrupts enable
//TIMSK |= (1 << OCIE1A); //interrupt on Compare Match A
}
attribute((always_inline)) static inline void UserTimer_Run(short skipTicks)
{

TCCR1 = 0; //stop the timer
TCNT1 = 0; //zero the timer
GTCCR |= (1 << PSR1); //reset the prescaler
OCR1A = skipTicks; //set the compare value
//OCR1C = 0;//skipTicks;
TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (1 << CS11) | (0 << CS10);//32 prescaler
//TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (0 << CS11) | (1 << CS10);//16 prescaler
//TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (0 << CS11) | (0 << CS10);//8 prescaler
TIMSK |= (1 << OCIE1A); //interrupt on Compare Match A
}

attribute((always_inline)) static inline void UserTimer_Stop()
{
TIMSK = 0;//&= ~(1 << OCIE1A);// clear timer interrupt enable
TCCR1 = 0;
TCNT1 = 0;
//GTCCR |= (1<<PSR1);
}

////////////////////////////////////////////

Hi sebascarra I am not able to create a pull request or attach a file here. I assume my settings as a new gitea user don't allow that?? I have made some progress on porting the code to the attiny85. It works, but not reliably as I have not tuned up the timings ( which are very critical). To set up the attiny85 I have - set the internal clock to 16MHZ (fuses L 0xF1, H 0XDF, E 0XFF ). But external 16mhz may be better? - tuned the OSCCAL value to 16MHZ - Modded the low level interrupt handling - the onewire pin must be PB2 (pin 7) on the attiny85 as PB2 is the only pin which handles rising, falling, change interrupts. The attachInterrupt api works the same as on the UNO. - Created the register set up for the attiny85 8 bit timer. The attiny85 timer has some subtle differences to the UNO and does not have a 64 prescaler (highest is 32). This means the timer values can not be exactly like the UNO. - I am using my FakeDS2413 as a test because the internal processing uses most of the onewire slave capability. - The attiny85 FakeDS2413 compiles to about 4000 bytes of flash and < 100 bytes of ram. ie there is plenty of space. Below are the attiny85 definitions I am currently using in lowlevel.h Be aware - Tweaking the attiny85 timings is not easy. There are only very rudimentary debug facilities usable on the attiny85. Bit like trying to do brain surgery through an earhole!! /////////////////////////////////////////// #if defined (__AVR_ATtiny85__) #define CLEARINTERRUPT GIFR |= (1 << INTF0) #define USERTIMER_COMPA_vect TIMER1_COMPA_vect __attribute__((always_inline)) static inline void UserTimer_Init( void ) { TCCR1 = 0; //stop the timer TCNT1 = 0; TIMSK = 0;// clear timer interrupts enable //TIMSK |= (1 << OCIE1A); //interrupt on Compare Match A } __attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks) { TCCR1 = 0; //stop the timer TCNT1 = 0; //zero the timer GTCCR |= (1 << PSR1); //reset the prescaler OCR1A = skipTicks; //set the compare value //OCR1C = 0;//skipTicks; TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (1 << CS11) | (0 << CS10);//32 prescaler //TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (0 << CS11) | (1 << CS10);//16 prescaler //TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (0 << CS11) | (0 << CS10);//8 prescaler TIMSK |= (1 << OCIE1A); //interrupt on Compare Match A } __attribute__((always_inline)) static inline void UserTimer_Stop() { TIMSK = 0;//&= ~(1 << OCIE1A);// clear timer interrupt enable TCCR1 = 0; TCNT1 = 0; //GTCCR |= (1<<PSR1); } ////////////////////////////////////////////
Poster

And I have just discovered I can't edit my post to fix the garbage either

And I have just discovered I can't edit my post to fix the garbage either
Owner

Hello,

So far I have not enabled repositories for "new" accounts, because the purpose is not to host code from anybody-on-the-internet, but that also means you can't fork, which doesn't help to share contributions. I'll take a look to find a solution to exchange pull-requests.

It's weird you can't edit your comments though.

Hello, So far I have not enabled repositories for "new" accounts, because the purpose is not to host code from anybody-on-the-internet, but that also means you can't fork, which doesn't help to share contributions. I'll take a look to find a solution to exchange pull-requests. It's weird you can't edit your comments though.
Owner

@IanF until I find a more permanent solution, I've allowed you one repository creation, you should be able to fork on gitea, and then push your code from your local repository.

@IanF until I find a more permanent solution, I've allowed you one repository creation, you should be able to fork on gitea, and then push your code from your local repository.
Owner

Well, actually, I've made a few tests, and it appears all user accounts can already fork on this gitea server, even if the repository limit has been reached (i.e. forking is a special case that bypasses that limit).

So @IanF you should be able to fork by clicking on the corresponding button on the top-right corner. You can then add this fork as a new remote to your local repository (let me know if you need help working with git), and then push your changes to your newly-created fork. Of course this means your work becomes public, no pressure on that if you don't want to :)

Once you have pushed to your fork, you can create a pull-request on gitea (which isn't even necessary if you just want to show some code to @sebascarra)

Well, actually, I've made a few tests, and it appears all user accounts can already fork on this gitea server, even if the repository limit has been reached (i.e. forking is a special case that bypasses that limit). So @IanF you should be able to fork by clicking on the corresponding button on the top-right corner. You can then add this fork as a new remote to your local repository (let me know if you need help working with git), and then push your changes to your newly-created fork. Of course this means your work becomes public, no pressure on that if you don't want to :) Once you have pushed to your fork, you can create a pull-request on gitea (which isn't even necessary if you just want to show some code to @sebascarra)
Poster

Hi youen

I have added the fork for the FakeDS2413.

Not entirely sure I have done this correctly as I am a newbie to gitea

Hi youen I have added the fork for the FakeDS2413. Not entirely sure I have done this correctly as I am a newbie to gitea

IanF, I saw your fork and it seems to be fine. I appreciate you forked the project and will review your code soon.

IanF, I saw your fork and it seems to be fine. I appreciate you forked the project and will review your code soon.
Poster

sebascarra,

To access the DS2413 (fake or real) from Arduino you will need a library. I have just uploaded my library to here

https://github.com/TechchatCom/OneWire-DS2413-Arduino-Library/tree/master

sebascarra, To access the DS2413 (fake or real) from Arduino you will need a library. I have just uploaded my library to here https://github.com/TechchatCom/OneWire-DS2413-Arduino-Library/tree/master
Owner

Thanks @IanF for sharing your code, I'll merge that when I find a moment. As far as I've seen there is no actual difference in the library itself (reminds me I probably already merged ntruchsess work back in the time). So actually, the library is already compatible with that microcontroller? I'll add your sketch as another sample, if you're ok with that.

And I'll probably order a few ATTiny85 next time I order electronic stuff, it looks handy and inexpensive.

Thanks @IanF for sharing your code, I'll merge that when I find a moment. As far as I've seen there is no actual difference in the library itself (reminds me I probably already merged ntruchsess work back in the time). So actually, the library is already compatible with that microcontroller? I'll add your sketch as another sample, if you're ok with that. And I'll probably order a few ATTiny85 next time I order electronic stuff, it looks handy and inexpensive.
Poster

Hi Youen,

Please go ahead with adding the FakeDS2413 as another sample.

There is no difference in the OneWire Slave library itself. I just copied it as a snapshot which I knew worked reliably.

I am making progress with the attiny85. But tweaking the timings is painfully slow.

Hi Youen, Please go ahead with adding the FakeDS2413 as another sample. There is no difference in the OneWire Slave library itself. I just copied it as a snapshot which I knew worked reliably. I am making progress with the attiny85. But tweaking the timings is painfully slow.
Poster

Hi Youen

The ATTINY85 OneWire Slave version of the FakeDS2413 is now working reliably. It has been running a few hours now with no errors.

It turns out there was a weird bug which had been making the OneWire reset handling behave very erratically. I know the reason for this behaviour but not the root cause. The bug does not appear to be in your code itself and I don't quite believe what I am seeing!!

I will tidy up the ATTINY85 code in the next few days.

I may also raise an issue if I can convince myself this bug is as weird as I think it is.

Hi Youen The ATTINY85 OneWire Slave version of the FakeDS2413 is now working reliably. It has been running a few hours now with no errors. It turns out there was a weird bug which had been making the OneWire reset handling behave very erratically. I know the reason for this behaviour but not the root cause. The bug does not appear to be in your code itself and I don't quite believe what I am seeing!! I will tidy up the ATTINY85 code in the next few days. I may also raise an issue if I can convince myself this bug is as weird as I think it is.
Poster

Hi Youen

I just saw you mentioned the ntruchsess work re attiny85. I had a look and it could not work.

I also searched for updates and I don't think that library is available anymore?

Hi Youen I just saw you mentioned the ntruchsess work re attiny85. I had a look and it could not work. I also searched for updates and I don't think that library is available anymore?

IanF, maybe your problems lie in the fact that you're relying on the internal oscillator. I suggest you do all your work using an external oscillator, and once everything you need to do works, then experiment by removing it. I'm using Chinese clone Arduino Nanos instead of ATTinys because the oscillator is on-board and they are so cheap.

IanF, maybe your problems lie in the fact that you're relying on the internal oscillator. I suggest you do all your work using an external oscillator, and once everything you need to do works, then experiment by removing it. I'm using Chinese clone Arduino Nanos instead of ATTinys because the oscillator is on-board and they are so cheap.
Poster

sebascarra

The attiny85 version is already working very reliably on the internal oscillator at 16mhz. See my earlier post.

The bug I mentioned in the same post is not directly related to the clock frequency or its stability.

sebascarra The attiny85 version is already working very reliably on the internal oscillator at 16mhz. See my earlier post. The bug I mentioned in the same post is not directly related to the clock frequency or its stability.
Poster

Hi Youen,

Would it be ok if I fork the attiny85 version of OneWireSlave please?

Hi Youen, Would it be ok if I fork the attiny85 version of OneWireSlave please?
Owner

Hello @IanF,
haven't got the time to read the last comments here yet, I'll let you know when I do (maybe next week).

About forking, I'm not sure to understand you question. You already have a fork, so now you can create a git branch if you want (though I don't see a problem in modifying the master branch anyway). But maybe you're not familiar with git? Anyway, in case you're wondering, you can't break the main repository (you don't have write access), so feel free to do what you wish with your fork.

Hello @IanF, haven't got the time to read the last comments here yet, I'll let you know when I do (maybe next week). About forking, I'm not sure to understand you question. You already have a fork, so now you can create a git branch if you want (though I don't see a problem in modifying the master branch anyway). But maybe you're not familiar with git? Anyway, in case you're wondering, you can't break the main repository (you don't have write access), so feel free to do what you wish with your fork.
Poster

Hi Youen,

I am not very familiar with git. But after reviewing a few tutorials, updating the existing fork appears to be the best option.

I have now uploaded the files which have been updated to support the ATTINY85 platform.

Hi Youen, I am not very familiar with git. But after reviewing a few tutorials, updating the existing fork appears to be the best option. I have now uploaded the files which have been updated to support the ATTINY85 platform.

@lanF I compared your repository https://gitea.youb.fr/IanF/OneWireArduinoSlaveATTINY85 with this one and there is little difference.
Did you push your changes ?

@lanF I compared your repository https://gitea.youb.fr/IanF/OneWireArduinoSlaveATTINY85 with this one and there is little difference. Did you push your changes ?
Poster

d-a-v No I haven't pushed the changes for the ATTINY85

d-a-v No I haven't pushed the changes for the ATTINY85

I'd love that you could considerate the best option that appeared to you above :)

I'd love that you could considerate the best option that appeared to you above :)

Hello,

Would it be possible to adapt this project with ATtiny85 for 1-wire + I2C?

I would like to try converting TMP117 (I2C) to 1-wire.

Hello, Would it be possible to adapt this project with ATtiny85 for 1-wire + I2C? I would like to try converting [TMP117](https://www.ti.com/product/TMP117) (I2C) to 1-wire.
Owner

@rtek1000 I haven't used this library for quite some time, but as far as I remember, I did merge contributions from other people for ATtiny85 support. So, yes, it should be possible to bridge between a 1-wire network and an I2C device.

The library will only help you send and receive raw data (bits and bytes) on the 1-wire side, you'll have to come up with a data protocol of your own.

Also, please double-check you have both an interrupt-enabled pin (for 1-wire) and separate I2C pins on the ATtiny85, I don't remember what are it's capabilities.

@rtek1000 I haven't used this library for quite some time, but as far as I remember, I did merge contributions from other people for ATtiny85 support. So, yes, it should be possible to bridge between a 1-wire network and an I2C device. The library will only help you send and receive raw data (bits and bytes) on the 1-wire side, you'll have to come up with a data protocol of your own. Also, please double-check you have both an interrupt-enabled pin (for 1-wire) and separate I2C pins on the ATtiny85, I don't remember what are it's capabilities.
Sign in to join this conversation.
No Label
No Milestone
No Assignees
5 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.