Jump to content

  •  

CNers have asked about a donation box for Cloudy Nights over the years, so here you go. Donation is not required by any means, so please enjoy your stay.

Photo

Yet another digital setting circles project: ESP-DSC

DIY equipment accessories planetarium software
  • Please log in to reply
145 replies to this topic

#1 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 18 March 2017 - 11:41 PM

So a few years ago I created TeensyDSC, a Teensy3.1/RX-VN 171 based digital setting circles solution.  I've been using that for a while now with great results, but I've always felt that it was too expensive (about $100 in parts).  The ESP8266 has been around for a little while now and seems to have stabilized (originally it was quite buggy) so I decided to see if I could get this cheap microprocessor + WiFi adapter to work and shave off over $60 in the process.

 

The result of that is ESP-DSC.  I've just finished bench testing it with a pair of 2.5k CPR encoders (10k after quadrature decoding) and it's run like a champ using SkySafari using the "Basic Encoder System" protocol at a 10Hz refresh rate.  The next step is mounting it on my scope and trying it out with my 10k CPR (40k quadrature) encoders.  Honestly, I'm not sure if the ESP-12E (or 12F) will have enough horsepower to keep up, but even still, I'd be pretty happy with it since it should only costs about $25-40 in parts.

 

More information can be found on my website here.

 

The next steps I have planned are:

  1. Test on my scope and 10K encoders
  2. Investigate adding a webserver for configuration
  3. Clean up the PCB design and make it smaller
  4. Design an enclosure that can be 3D printed

IMG_2088.jpg


Edited by synfinatic, 18 March 2017 - 11:48 PM.

  • ccs_hello, txmnjim, CharLakeAstro and 2 others like this

#2 halx

halx

    Vendor

  • ****-
  • Vendors
  • Posts: 2,585
  • Joined: 28 Sep 2010
  • Loc: Albany, California, USA

Posted 19 March 2017 - 12:09 AM

Awesome! Thank you for sharing the progress, Aaron.

 

Edit: I didn't find any information for 2.5k CPR encoders you have tested on the website. Where I can get them?


Edited by halx, 19 March 2017 - 12:24 AM.

  • Chirp1 likes this

#3 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 19 March 2017 - 01:07 AM

They're standard US Digital S2-2500-250-I-D-D encoders you've no doubt seen a few dozen times.  Everyone calls them 10K encoders (due to the quadrature decoding), but natively they're just 2500 CPR (clicks per revolution) which is kinda confusing.



#4 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 19 March 2017 - 10:22 AM

So I went to bed and as I'm trying to fall asleep I realize I can optimize some of the interrupt handling code and make it faster.  This morning I fed the cats, made coffee and updated my code (in that order).  That's when I notice I should be able to optimize the code even further or add some error detection for interrupts which weren't handled properly.  Since the original code was very strict in trying to handle the interrupts, I decided to opt for error detection rather then optimization.

 

TL;DR; My updated code now will tell me if I "drop" an interrupt which would introduce some error.  Much more accurate then the testing I've done so far.

 

The good news is that no problems reading a single encoder moving.  The bad news is that occasional problems when both encoders are moving at the same time.  It's not a lot, but it's enough to cause problems.

 

So the updated next steps are:

  0. Fix interrupt handling


Edited by synfinatic, 19 March 2017 - 09:17 PM.


#5 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 19 March 2017 - 09:16 PM

So I spent most of the day optimizing the code and realistically speaking not making any significant improvements.  At this point I'm going to say that the ESP8266 can't keep up with two 2500 CPR encoders using the Arduino programming environment.  Maybe it would work using the native SDK, but so far I haven't found any evidence for that and so I haven't bothered to test that theory yet.

 

The good news is that there are a number of other solutions and I've documented them here on my blog: https://synfin.net/s...-works-not-well


  • halx likes this

#6 DAVIDG

DAVIDG

    Hubble

  • *****
  • Posts: 12,982
  • Joined: 02 Dec 2004
  • Loc: Hockessin, De

Posted 20 March 2017 - 09:25 AM

 Do you have any feeling for  what resolution the  encoders  wouldn't   have a problem ? I have built a similar unit using an ESP12E module which cost  under $10 It  has  a built in USB port so no need for the separate FTDI board for programming and one can directly wire the encoder to the module for easy construction.  I'm using 8192 encoders.  A couple of my club  members have built them and we haven't seen any issues with dropped interrupts or encoder count errors. 

 

                 - Dave 

 

ESPDSC.jpg



#7 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 20 March 2017 - 09:49 AM

2500 CPR/10K encoders almost work.  I bet they would work great if you had a go to scope since they don't move fast.  But someone with a push-to dob who moves both axis quickly would see a few dropped interrupts.  You may not even notice it during alignment, but over the course of the night things would get progressively worse. I don't see any dropped interrupts if you move only one encoder.

 

As I'm sure you know, if only one encoder is moving, the interrupts happen sequentially and never occur at the same time.  Once you add a second encoder, the chances of an interrupt collision goes from 0 to greater then 0.  According to the info I've read, the ESP should queue up the interrupt if it is in an interrupt handler when another pin detects a voltage change.  However that queue is limited and if you overrun it, then you'll start dropping interrupts.  Maybe tonight I'll plug the board into my 10K CPR encoders on my scope and see just how bad it is.  For a single encoder it might work.

 

Looks like you've got a NodeMCU?  I'd be curious to compare your code vs. mine if you don't mind sharing.  All my code is posted up on github: https://github.com/s...ter/src/esp_dsc  To get the code to work, copy config.h.sample to config.h and edit to taste. You'll probably also need to edit esp_dsc.h to assign the encoder pins.

 

The code that is published currently only will detect a missed interrupt on the DEC encoder's B channel.  The rest of the error detection has been optimized away.


Edited by synfinatic, 20 March 2017 - 09:51 AM.


#8 hjd1964

hjd1964

    Messenger

  • *****
  • Posts: 409
  • Joined: 24 May 2012

Posted 20 March 2017 - 11:54 AM

According to the info I've read, the ESP should queue up the interrupt if it is in an interrupt handler when another pin detects a voltage change.

 

I wonder if ISR's for RISING and FALLING edge instead of just CHANGE would help?  It would require using four pins per encoder I guess.  Might make for slightly faster ISRs too since you know the pin state going in.



#9 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 20 March 2017 - 01:30 PM

Hi Howard,

 

I suppose I could do that, but that won't reduce the total number of interrupts which I believe to be a bigger problem then the amount of work done in the ISR.  Or in other words, I believe the ESP has to spend significant clock cycles setting up/tearing down the ISR (modifying the stack, etc) and that's the root cause of the issue.

 

As it is, my code avoids digitalRead() on 3 of the 4 pins- instead I just flip state.  This works fine as long as we don't drop interrupts.  On the 4th pin, I do a digitalRead() and compare it to the previous state.  If it is the same as the previous state, then I know I lost an interrupt somewhere.  Of course it's possible that digitalRead() is really really slow... I don't have a signal generator to do a proper bench test, but maybe I can hack something.  Have to think about that.

 

Honestly, I suspect I need to find almost an order of magnitude improvement in performance to prevent lost interrupts at this point.  Remember, my goal isn't to support these encoders, but rather the 40K (10K CPR) encoders on my scope.  Right now, I don't see any way that the ESP8266 can do that on it's own based on my results so far.



#10 hjd1964

hjd1964

    Messenger

  • *****
  • Posts: 409
  • Joined: 24 May 2012

Posted 20 March 2017 - 02:36 PM

I suppose I could do that, but that won't reduce the total number of interrupts which I believe to be a bigger problem then the amount of work done in the ISR.  Or in other words, I believe the ESP has to spend significant clock cycles setting up/tearing down the ISR (modifying the stack, etc) and that's the root cause of the issue.

 

I'm not suggesting this for the very slight reduction of work in the ISR, I doubt your rates (for a 10k anyway) are high enough to matter in that regard.  I like how it doubles the amount of time between interrupts on a given pin.  I wonder if the ESP is busy elsewhere and keeps interrupts disabled for just a hair too long and your pin triggers another interrupt before the first is serviced.

 

Agree, I see no way is this going to get a pair of 40k encoders working at similar deg/s speeds.



#11 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 20 March 2017 - 03:16 PM

I suppose I could disable WiFi for the next test.  That would give a good indication if it's too busy elsewhere.

 

The thing is that when you enter an ISR, interrupts are disabled globally- not just for that pin. The fact that I don't see any dropped interrupts when only one encoder is being rotated tells me that the ESP is capable of handling the CHANGE interrupt on a single pin. Hence I don't think distributing the interrupts to more pins is going to help.

 

Anyways, I should definitely give a single 10K encoder a try tonight.  I'm curious if the ESP can keep up- it may only be a problem when two interrupts occur simultaneously.  So I just did the math and at 80Mhz, 40K would work out to 2000 instructions per interrupt.  That seems like plenty considering what is happening.  Of course there is additional overhead for WiFi, etc.

 

That said, IIRC, there is a way to run the ESP at 160Mhz.  Eats more power, but my design has a beefy 3.3V regulator so it should be no problem to try that.  So I should try that as well.



#12 hjd1964

hjd1964

    Messenger

  • *****
  • Posts: 409
  • Joined: 24 May 2012

Posted 20 March 2017 - 04:12 PM

The timing requirements are more critical with two encoders, each has to (potentially) wait for the other + anything else that might disable interrupts for a moment here and there.  With a single encoder it never waits for itself, either A or B never both.

 

IDK if this will help, but I wouldn't be surprised if it did.  I also wouldn't be surprised if there was some obscure problem with having eight pin interrupts enabled at the same time on this thing. :)



#13 mconsidine

mconsidine

    Explorer 1

  • -----
  • Posts: 94
  • Joined: 16 Nov 2006

Posted 20 March 2017 - 07:56 PM

I think digitalRead has a lot of overhead
http://forum.arduino...ic,46896.0.html

Mconsidine

#14 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 20 March 2017 - 09:09 PM

That link is talking about the Arduino AVR based boards (Uno, Mega, etc) which are slow.  This page gives the numbers: 

 

http://syncchannel.b...t-shootout.html

 

If you scroll down to the comments, the ESP8266 @ 160Mhz digitalRead() is 0.3us vs 5.4us for the Arduino Uno.  

 

Anyways, I bumped the speed up to 160Mhz and ran my tests.  Still dropping interrupts when spinning both encoders quickly.  I also tried one 40K encoder and it's able to keep up as long as I don't try to move it very quickly (spin the encoder between your thumb and finger).  Normal deliberate moves are ok.  I've glued a toothpick to the encoder and unless I spin it very fast it keeps up fine.

 

Honestly, I'd be hard pressed to say that 160Mhz is any better then 80Mhz.  The 40K encoder all by its own can do roughly a constant 1 rotation/sec (maybe more?) before things break.

 

Edit: edited the code to disable WiFi and ran it at 160Mhz to see if that helps things.  I'm going to subjectively say "yes", but only a little.  


Edited by synfinatic, 20 March 2017 - 10:50 PM.


#15 mconsidine

mconsidine

    Explorer 1

  • -----
  • Posts: 94
  • Joined: 16 Nov 2006

Posted 21 March 2017 - 01:35 AM

How do things look if you strip out the code that enables multiple clients to connect to the esp? Ie write it for only one client...
mconsidine

#16 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 21 March 2017 - 09:18 AM

Well I disabled all the WiFi/client handling code and it made no significant difference.  Without a proper signal generator, I don't have a means of actual measuring changes like that.  

 

Doing some research shows that I should be able to come up with a poor mans signal generator using an Arduino/etc to generate two PWM signals 90deg out of phase.  I probably wouldn't be able to change the frequency very well, but could easily emulate a constant rotation speed of the encoder.  Not sure how easy to do this is yet.  Would be nice to be able to to get an accurate measure of accuracy without relying on a digitalRead() (which I believe to be fast, but still a lot slower then flipping a boolean).

 

The other thing I'm looking into is using something like a pair of ATTiny84 to process the encoders.  I think one should be able to keep up with a single 10K encoder.   I have some old Arduino Uno's which are basically the same chip, but just have more pins so I could do a test. Nice thing about them is that they're only $1/ea vs the $5 US Digital wants for their encoder counter chips.

 

Or use two ESP8266's and each one only handles a single encoder and they communicate via serial.  That should work as long as one of them still has enough power to handle WiFi.

 

Or wait a while for the new ESP32 which is a more powerful dual-core wifi/bluetooth solution to stabilize.  



#17 mconsidine

mconsidine

    Explorer 1

  • -----
  • Posts: 94
  • Joined: 16 Nov 2006

Posted 21 March 2017 - 09:34 AM

Can I assume you tried the advice here?

  http://www.esp8266.c...php?f=32&t=8855

mconsidine



#18 hjd1964

hjd1964

    Messenger

  • *****
  • Posts: 409
  • Joined: 24 May 2012

Posted 21 March 2017 - 09:48 AM

You would expect some not insignificant speed up by going to 160MHz...

 

What about adding ICACHE_RAM_ATTR to the ISR's?



#19 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 21 March 2017 - 11:56 AM

Can I assume you tried the advice here?

  http://www.esp8266.c...php?f=32&t=8855

mconsidine

No.  Since I never enabled WiFi in my later tests and didn't see a significant increase in performance, I honestly don't see much value.

 

You would expect some not insignificant speed up by going to 160MHz...

 

What about adding ICACHE_RAM_ATTR to the ISR's?

Haven't tried that.  And honestly, not sure what that is, so I'll have to research it. :)



#20 hjd1964

hjd1964

    Messenger

  • *****
  • Posts: 409
  • Joined: 24 May 2012

Posted 21 March 2017 - 12:26 PM

 

Can I assume you tried the advice here?

  http://www.esp8266.c...php?f=32&t=8855

mconsidine

No.  Since I never enabled WiFi in my later tests and didn't see a significant increase in performance, I honestly don't see much value.

 

You would expect some not insignificant speed up by going to 160MHz...

 

What about adding ICACHE_RAM_ATTR to the ISR's?

Haven't tried that.  And honestly, not sure what that is, so I'll have to research it. smile.gif

 

Most code on the ESP8266 runs right from flash memory [or is it cached in RAM sometimes too?], via a multi-channel SPI interface (4 channel?)

 

There's an IRAM area also, instruction RAM.  It's small (32k?) so is used only for code that needs to be there, should [be] faster I think.  Not sure if this is taken care of automatically by Arduino processing or is it up to us?  The Sketch does compile with it added, I don't have anything hooked up to test further:

 

void ICACHE_RAM_ATTR HandleChanRA_A() {

... etc.


Edited by hjd1964, 21 March 2017 - 12:32 PM.


#21 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 21 March 2017 - 12:33 PM

I'll definitely give that a try tonight when I get home!



#22 drneilmb

drneilmb

    Apollo

  • *****
  • Posts: 1,088
  • Joined: 05 Jan 2017
  • Loc: Decorah, IA, USA

Posted 21 March 2017 - 02:26 PM

If you want to make a test bed to feed quadrature signals into your system, I've got an Arduino sketch here http://neilmb.github...quency-DDS.html that does quadrature waveforms at audio frequencies. It's set up for sine waves, but the translation to square waves is pretty straightforward.



#23 halx

halx

    Vendor

  • ****-
  • Vendors
  • Posts: 2,585
  • Joined: 28 Sep 2010
  • Loc: Albany, California, USA

Posted 21 March 2017 - 03:07 PM

Aaron, you are reading my mind :) I planned for asking you to try the 160MHz option, but you've done that while I was at work. Then, being thinking about two chips instead of one as they are really cheap, but you have been poking that idea already... Though, in order to interface them equaly, I had in mind building a simple Android bridge app (content provider) which would simulate a single BT or Wifi adapter to the PushTo/GoTo app.



#24 DAVIDG

DAVIDG

    Hubble

  • *****
  • Posts: 12,982
  • Joined: 02 Dec 2004
  • Loc: Hockessin, De

Posted 21 March 2017 - 03:35 PM

 One thing you might try is to remove the level shifter. On my ESP12E  module my encoders were dropping counts. When I directly wired them into the module no missing counts. The ESP12E looks to have a built level shifter and is 5 volt tolerant at least the 7  modules I have tried all seem too. The other thing to be careful with  is trying to move the encoders by hand. Any torquing of the shaft can easily give wrong data that looks like your missing counts. I had to install mine on the scope and when I did I could move the scope as fast as I could in both axis multiple times and then return to index marks and the raw encoder reading would only be off by few counts at most which is well within the mechanical play in my system. 

 

                 - Dave 



#25 synfinatic

synfinatic

    Viking 1

  • *****
  • topic starter
  • Posts: 850
  • Joined: 22 Dec 2013
  • Loc: San Jose, CA

Posted 21 March 2017 - 04:07 PM

If you want to make a test bed to feed quadrature signals into your system, I've got an Arduino sketch here http://neilmb.github...quency-DDS.html that does quadrature waveforms at audio frequencies. It's set up for sine waves, but the translation to square waves is pretty straightforward.

Thanks.  I'll take a look at that tonight.

 

 One thing you might try is to remove the level shifter. On my ESP12E  module my encoders were dropping counts. When I directly wired them into the module no missing counts. The ESP12E looks to have a built level shifter and is 5 volt tolerant at least the 7  modules I have tried all seem too. The other thing to be careful with  is trying to move the encoders by hand. Any torquing of the shaft can easily give wrong data that looks like your missing counts. I had to install mine on the scope and when I did I could move the scope as fast as I could in both axis multiple times and then return to index marks and the raw encoder reading would only be off by few counts at most which is well within the mechanical play in my system. 

 

                 - Dave 

 

I was going to going to say that the spec sheet says it's 3.3V only and just because it works now, doesn't mean it won't die later.   Then I did a Google search and came across this post on Facebook by the CEO Teo Swee Ann saying that indeed the GPIO pins are 5V tolerant.  https://www.facebook...hc_location=ufi

 

Crazy world we live in when Facebook is more trustworthy then a datasheet!  Definitely worth testing with out the level shifter and saves a buck. :)

 

Anyways, I've been doing my tests lately using toothpicks glued to the flat face of the encoder shaft and rotating the shaft by only touching the toothpick.  I think that should be safe enough to prevent applying torque to the shaft itself and corrupting the inputs.  




CNers have asked about a donation box for Cloudy Nights over the years, so here you go. Donation is not required by any means, so please enjoy your stay.


Recent Topics





Also tagged with one or more of these keywords: DIY, equipment, accessories, planetarium software



Cloudy Nights LLC
Cloudy Nights Sponsor: Astronomics