ISS Alert- should this work?

What’s wrong with good ol’ blinky… it’s quite an achievement compiling and uploading code to make it blink… After playing with the SDK for a whole new chip that is likely to replace the ESP8266 next year, and having to play with the lower level C stuff to get it to do anything, I should know! :laughing:

Worth a look… perhaps not so good for my bank account… that’s three times as many reasons to get something that looks tempting! :laughing:

That’s a SH1106 based OLED, so you might be able to switch to this library (untested by me), do a few minor tweaks, and it just work. If it’s that easy, you can then take advantage of the basically double vertical space to have more stuff on the display.

1 Like

Hmmm, interesting. I’ve just corrected my own lat/long and tested again. I’m in the middle of a 6 minute overhead pass right now, but looking at the ISS Live app on my phone, the station is overhead Algeria and is not quite able to be seen from the UK.

There is weirdness here methinks! :frowning_face:


1 Like

Bummer! That particular library is for Arduino only, not for the ESP8266. Shame. It won’t compile for ESP8266. Never mind, there’s always U8G2 by Oliver. I’ll try that one out.


1 Like

I am using the UTC time, unmodified.
Longitude was positive. i made it negative.

Now the timer says 15 minutes, but the station is over the middle of the Pacific, according to NASA’s real-time website.

I had a similar problem today. The alert said overhead but on checking, it was over Algeria. My “horizon of visiibility” apparently extends almost to Barcelona – according to the ISS Live app for Android – but Algeria is a fair bit further South.

I’ll be having a look when I have time. I know that UTC time is spot on, because I checked. I know my Lat/Long are correct as I’ve done lookups and got my actual Street name in response – so, I’m thinking that maybe the ISS API is not returning correct data, or there are gremlins afoot!


1 Like

Implausible. It’s over the middle of Africa, timer says 1 hour.

It got that one right, but it says there’s another flyover in 1:30.

That’s implausible.

secrets.h- PIO didn’t save a copy in lib deps. It isn’t loading ssid or password from secrets.h.

When I took my logon credentials out of the .cpp file and put them in secrets.h, I lost WiFi.

I created a file and a folder in lib deps, but it didn’t work.

Why should it? It’s not a library. Only cached library files go in .pio/lib_deps.

If you’re not editing include/secrets.h (which is where it has always been), you’re editing the wrong file. :stuck_out_tongue:

How are you losing it? Via pulling from git? If so, you need to instruct git that you want to preserve your local copy of the file after you’ve filled it in.

Really? And where do you think it would be in roughly 1.5 hours (aka 1h30mins), given where it was 1.5 hours earlier? The ISS does pass over head multiple times in succession. It just won’t be directly overhead… i.e likely to be to the south the first pass, nearer to directly overhead the second, and to the north the third time (if you’re lucky to within 10 degrees of a third pass), or something like that.


Indeed… and to be honest it’s probably the better way to go… more universal display support for starters. Adafruit GFX is just for convenience since there was already Adafruit libraries in use… I would probably have used FastLED for the WS2812s if I had been writing this from scratch, and U8G2 for the OLED.

Maybe V2 will be a complete re-write… at the moment it’s looking like the only similarity to the original code will be the ISS notify lookup, and that may also go if it’s inaccurate or I find a more authoritative API source like something from NASA or ESA.

1 Like

Ummm, from

Joey from Australia
During a 24 hour period, how many times does the ISS orbit the Earth?
Well, the space station orbits Earth about every 90 minutes, so that means in a 24 hour day, the space station orbits approximately 16 times.

So, unless you think that “1:30” is one minute 30 seconds, then it is plausible. (The code only displays hours and minutes.)


1 Like

Oh no, you didn’t… not the fifth grader answer! :laughing:

It actually calculates, and says: That's 04 hours, 48 minutes and 39 seconds from now… so it’s basically impossible to misunderstand that one :wink:

I now have it shoving the unixtime into TimeLib, so I can manipulate time-zones easily… giving this…


I pulled out the datetime that the Open-Notify ISS API reports when doing a query, and do you notice someing odd there… even though the current UTC time is 09:47 10:03, the API time is still back at 09:12… it seems if I change the number of entries to pull it will basically report the current time, but it looks like the API caches queries… it will be interesting to see how long for… maybe that adds a bit of error itself since it may not be tracking changes to the orbit as well as could be done.

Now, if you look at the NASA sighting opportunities page… this corresponds quite nicely with the highlighted listing if you take into account that

  1. Maryborough is just the nearest listing to me (so different lat/long - about 100km away)
  2. that the NASA times must be local time - they have just completely failed to mention the timezone their times are listed in thus confusing you if you think they’re in UTC or something! :man_facepalming: :laughing:
  3. that it is probably visible over my horizon one pass before it’s visible in Marybourgh, hence why I may see it at 00:36 my time, but it’ll be visible in Marybourgh on the next pass, just under 1.5 hours later…

Juicy stuff, eh?

1 Like

Even worse, current UTC time is 10:03:42 :grin:

If it is caching, or something between you and Open Notify is caching, then you can easily force a cache break by adding a ridiculous parameter at the end. I had to write this a while back when people’s browsers were caching a download that I had updates. I used JavaScript to generate a random number and tagged it on the end of my URL with “&CacheBreak=nnnnnn” so every time the link was clicked, it generated a new URL and forced a cache bypass.

I wonder if adding the UTC unixtime, in seconds, from the UTC API onto the end of the URL for Open Notify would help? Something like:

http.begin(client, "" + String(latitude) + "&lon=" + String(longitude) + "&alt=" + String(altitude) + "&n=5" + "&UTC=" + String(currentTime);

That should work, at least until “this time tomorrow” – assuming that something is caching.

I went over to and on the front page, at the bottom is the “current position of the ISS”. I have ISS Live open on my phone and constantly updating. The two do not match up! It’s showing (+0.2 to +.0.3) lat and (+0.8 to +1.2) long of a difference – so that’s probably not going to help.



I had no idea the station was going so fast.
The thing decided I guess the angle was bad, so it went to 3 hours for the next flyover.

I’m going to wire up a bunch of ISS lamps for my family now and put this project to bed.
Secrets.h is a really nice feature I’d like to include, but I’m not going to keep a copy for each unit I make. I will want to use it correctly when I start doing OTA. I plan to have several ESP32 and 8266 devices around.

I downloaded your secrets.h and edited it, saved it in the pio/lib deps folder. Now it’s in /include, but the WeMos is elsewhere. I’ll repeat soon.

I’m looking at the new version, comparing it to the original. You’ve made a whole new thing.
I didn’t learn JSON, but I look forward to referencing this when it comes up again in a few months.

Why would having additional Adafruit libraries be bad? Why not GFX?
I still can’t really get much useful info from a library.

The bias I bring would avoid excess baggage. I would avoid a library for being too long.
Is that a thing?
In Google, it was worthwhile to go from jpeg to jpg and html to htm among other things, to reduce non-displaying character count and tweak relevance at the margins. No similar thing exists here?
But bytes consumed by non-coding code must be expensive. And I worry about excess text in flash memory finding its way into the running program. That’s probably a thing.

Well, that was you problem… you downloaded the file and put it in the wrong place, because you didn’t look at the repository and see where it belonged. Not using the standard options of using git to sync the code locally, or downloading the zip file is just making your life harder, and making so you can get things wrong…


Web coding is nothing like C++ coding, mainly because with web coding you had to do a lot of optimisation manually, and it wasn’t compiled into binary form / machine language for a processor to interpret directly.

Making fears like this …

… irrelevant. The compiler will optimise a lot of things in the code, and make it just work. Making things shorter is likely to make it so you make mistakes. The only real optimisation you want to use with these processors is that strings of text should be stored in the flash memory, but only because there is more of it.

Libraries are used in Arduino code to make life easier. Which library you use is up to you, and what your intended purpose is. I would have used the U8G2 library instead of the Adafruit GFX and SSD1306 library because it supports many more displays, making it a one line change to change display types completely. Adafruit write some good stuff, but it is designed to support just the hardware they distribute, not be more universal or as optimised as it could be.

Well, talk about clutching at straws… it only just counts as being on the horizon. I wish the API also returned the max height degrees… could probably discount passes that are right on the horizon then.

It does look though that it’s next pass in just about 1h23 minutes will be directly overhead though…

EDIT: Spelling, spelling, spelling! :rage:

A library is a tool that someone has created to make life easier for themselves and others. Like a specialist hammer. The WiFi library, for example, saves you fiddling in register hell – you just connect to an SSID with a password.

You don’t get information out of a hammer! :wink:

A library is made up of a number of compiled modules. Each one doing something specific, in the minimum amout of resources. The library might contain hundreds of modules – however, your code might only need 4 or 5.

The link phase of compilation copies out those modules you actually used, plus any that they themselves used and so on. The rest is ignored and forms no part of your final code.

There is no excess text in flash, unless you put it there.

Code in your program that’s never called will most likely be optimised out – it won’t appear in the final output.

If I remember, the D1 Mini has 4Mb flash. I’ve been coding since 1981 when I had 1Kb to fit everything into. You youngsters have it soooooo easy these days!

If you want to save masses of bytes, stop using the Arduino framework and “language”. This is pinMode():

void pinMode(uint8_t pin, uint8_t mode) { 
    uint8_t bit = digitalPinToBitMask(pin);    
    uint8_t port = digitalPinToPort(pin);      
    volatile uint8_t  *reg,  *out;

    if (port == NOT_A_PIN) return;

    reg = portModeRegister(port);
    out = portOutputRegister(port); 

    if (mode == INPUT) {
        uint8_t oldSREG = SREG; 
        *reg &= ~bit; 
        *out &= ~bit; 
        SREG = oldSREG; 
    } else if (mode == INPUT_PULLUP) {
        uint8_t oldSREG = SREG; 
        *reg &= ~bit; 
        *out |= bit; 
        SREG = oldSREG; 
    } else { 
        uint8_t oldSREG = SREG; 
        *reg |= bit; 
        SREG = oldSREG; 

A lot of code. All those cli() function calls stop interrupts – that affects millis() and stops it counting up.

In the end, the code boils down to one or two instructions:

    DDRx = something;
    PORTx = something;

If you write in plain AVR C/C++ instead if using the Arduino “stuff” your code will be miles shorter.

  • Standard blink sketch = 928 bytes flash;
  • Using my digitalToggle() function = 890 bytes;
  • Using AVR C++ but using delay() = 598 bytes;
  • Using AVR C++ and AVRLib’s _delay() = 158 bytes;
  • Using AVR assembly language and the C++ compiler = 162 bytes.

Interesting that assembly is bigger – that’s because g++, the compiler, creates interrupt handlers for all 20 odd interrupts at a cost of 4 bytes each. A proper assembler would not.

It’s possible to get even smaller using a timer/counter or the Watchdog Timer – but that’s not really representative – however doing so frees up the CPU to do real work as opposed to flashing an LED.


1 Like

I can understand the English parts, but it’s fuzzy where the boundary is.

I know what libraries do and why we have them, but it’s currently the bigger of my two beefs with Arduino. I should have been learning about libraries, but the only interaction is installing them with the library manager. When I was starting, the stuff I was into, I could have been making simple libraries. Lost opportunity. I didn’t know the examples came from libraries.
The other angry is not knowing how much hand-holding was going on at compile. I feel kinda lied to.

I’ve seen examples written for ESP-IDF that don’t look like Arduino. But that’s the only perspective I have so far. If there’s no advantage in shorter code, I guess it’s okay that whatever I add is written in Arduino- but I’ll be going for strict C++. I like how much support is available.

I’ve been yelled at by y’all for downloading libraries. I had a big collection, now on USB drive. I confess to downloading libraries still, but I’ve been leaving them in Downloads and extracting there.
And they’re thousands of items, so I don’t want them hogging up my desktop.

I’ve read what you’re telling me about non-coding code being excluded somehow magically by6 the black box. Thank you for convincing me. Normally, I want to take the black box apart.
I’m a DNA guy. There is so much garbage code in your DNA, it’s amazing there’s any meaning in it at all. But you can’t distill it.

I’ve never seen ‘case’ used in the wild before, and I really like it. The machine states thing, I dig it.

And yeah, the ESP machines have lots of space. I can’t wait to be able to upload several binary files and run from both processors*. But I’ll have to wait. The bright side of that for you is that I’ll be bugging the Espressif people. They do respond. You usually get a second response.
That’s not on the list yet. One of the biggest problems you face with me is the spectrum of projects I was trying to work, all different and stretching what I know. Normal things come easy to me, and I have to factor in some kind of multiplier to slow me down.

And again- holy crap, you guys really hooked me up.
If you need anything genetically engineered…

  • Are the .bin files I find in PIO the same ones for the ESP Download Tool?

Don’t… that is exactly their purpose… so you DON’T need to know. If you want to light a Neopixel blue at 50%… do you really want to have to delve through the many, many page datasheet on how the WS2812 (which is what a Neopixel really is) timing works, and how to drive the thing? Nope, you just want to be able to copy some code, that makes it light, tweak the oclour, and carry on.

That would be right… things like digitalWrite, digitalRead, pinMode, etc, etc, don’t exist in the ESP-IDF - they are Arduino helper functions. As far as code length, compilers are very smart beasts, and optimise A LOT. If you say created a variable, shoved a value into it, and then used the variable in the code… the compiler would say whilst doing the conversion to the language the processor understands that there’s no need to do all that work… and just shove that value in right in, skipping a few steps.

I get you on that point… but you need to know when to stop. Do you keep digging around (and probably confusing yourself), or keep going at the current level. Only you can answer that question, but I usually look at whether I have time to look at the lower level stuff, or is the project I’m working on now stalling because the focus is being split too much.

You don’t want to know the number of projects I have in various states of development, some of which will probably never get finished! :open_mouth: That’s why it’s good to just pick a few good works, and work on them, and then do that over and over again.

Most likely… the .bins are uploaded with

What I would actually recommend if you are going to do this…

… would be to use the WifiManager library to make it so you don’t hard-code the Wifi SSID and password into the program, but can set and change it post-upload. It’s probably getting a bit too close to Christmas to have enough time to code and test it properly (as I only know it is possible, I haven’t done it myself yet), but it would also be possible to have it so that all of those parameters could be set via the WifiManager interface - meaning they can be changed if say a wifi access point/router is replaced, or they move, etc, without needing to re-compile the code - you’d just go into the Wifiman page and set the new configuration values.

Maybe that can come later with a update :wink:

Speaking of which… there it goes again… this pass is basically overhead since it’s nearly 11 minutes, and the next will be shorter one, and then that’s probably it for 12 hours or so…

Edited, again for spelling. Sigh!

Yup – that’s about all you need to do. There’s no learning about libraries other than:

  • How to write one;
  • How to use one.

That’s it. You can delve into the source code if you wish, but that way, many rabbit holes lie. You could be down there for days!

Well, the whole Arduino concept was originally to get students building stuff quickly to get a handle on what they were learning. It sort of grew from that - in a manner very similar to the Raspberry Pi’s original design. It too was because kids were doing tech courses at University and couldn’t program a computer. IT learning back then was using Microsoft Office. Eben Upton was at Oxford University and dismayed at the standard of abilities of prospective students.

See my brief description of pinMode() further back. Lots of stuff happening below the quilt covers to stop you doing something daft and smoking the board. But it saves you having to read the data sheet to determine that you must:

  • Write a 1 bit to the pin position in the appropriate DDR register to make a pin an OUTPUT;
  • Write a 0 bit to the pin position in the appropriate DDR register, AND write a 0 bit to the pin position in the appropriate PORT register to make a pin an INPUT;
  • Write a 0 bit to the pin position in the appropriate DDR register, AND write a 1 bit to the pin position in the appropriate PORT register to make a pin an INPUT_PULLUP;

That’s all there is to it, but what is easier pinMode(3, INPUT_PULLUP) or:

// Make D3 an INPUT Pin.
DDRD &= ~(1 << DDD3);
// Turn on PULLUP resistor.
PORTD |= (1 << PORTD3);

I know which one I prefer, but I know which one is by far the more efficient.

By the way, in both the Arduino IDE and PlatformIO, all the core files for the appropriate platform are compiled into a library (usually core.a is it’s name) and then linked with your code. Only the modules you have used are linked into your final firmware file ready for uploading.

They don’t, well they do but …

When you or someone write a library for the Arduino, for example, it is written in a particular way. An examples directory/folder, if supplied, will cause the examples for that library to be installed when you add the library. The layout is:


It is possible to have other folders in there as well, my libraries have a docs folder – to describe how to install and use the library and a bit about the examples. There will usually be screen shots for the breadboard setup and so on. Those additional folders are ignored by the Arduino IDE.

The good news is, PlatformIO can use Arduino libraries in this format. Most useful indeed. And the code in use should also be the same if you are using the framework = arduino option in platformio.ini.

Because you don’t need to download them. using lib_deps does that for you. However, if your internet is flaky, then having a download is helpful.

I’m developing a bunch of libraries for Arduino and PlatformIO. I have a layout like this:

       ... as above.
       ... as above.

Each library folder is as described above. In my platformio.ini I have something like this:

; Where to find my various PlatformIO libraries. This is a
; relative path from the project directory to the directory
; named "PlatformIO_Libraries" under which, each library is
; to be found in it's own sub-directory.
; In each subdirectory is the source and header files. There's
; no need for "lib_deps" in this case.
lib_extra_dirs = ../../../../PlatformIO_Libraries/

So, I don’t have to code a bit, test a bit, publish the library – which may not be complete – to and/or GitHub then mess about changing versions, adding and removing bugs and features, and so on, then having to republish everywhere. I do what I want locally, and when I’m finished I’ll publish.

In my code I just have the appropriate headers:

#include "AVR_wdt.h"

Then use the code:

#include "AVR_wdt.h"

// LED pin for the WDT to flash.
#define WDT_LED 7

void wdtInterrupt() {
    digitalWrite(WDT_LED, !digitalRead(WDT_LED));

void setup() {
    // Initialise Serial.

    // Do the pins. Pin 7 is for the WDT interrupt.
    pinMode(WDT_LED, OUTPUT);

    // Enable the WDT to fire every second.
    AVRwdt.begin(AVR_wdt::WDT_TIMEOUT_1S, wdtInterrupt, false);

    // Inform the user as to what will happen.
    Serial.print("WDT will reset: ");
    Serial.println((AVRwdt.willReset()) ? "YES" : "NO");

    Serial.print("WDT will interrupt: ");
    Serial.println((AVRwdt.willInterrupt()) ? "YES" : "NO");

void loop() {
    // Flash the builtin LED every 5 seconds.
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

Job done. The built in LED is flashed every 5 seconds in the loop() and the LED on D7 is flashed every second by the watchdog.

Long story (too long!) short, I have lots of libraries in a safe place, and I can use them for my AVR code in PlatformIO and/or the Arduino IDE without having to lib_deps them all - just do the above with the very top level folder and either it’s full path or a relative one. All the libraries in that folder and sub-folders will be able to be used as required.

So, you can still use your USB and/or Downloads folder for your libraries with a little organisation of the folder structure.

Me too! I love to know how things work. I have two mottos in life:

  • Don’t think, find out!
  • How the f*ck does that work!

Well, it’s called “junk” DNA, but nobody knows, yet, if it really is junk. I love the fact that an onion has more DNA than a human. Makes perfect sense to me. Onions are complex creatures. :grin:

I’m tempted, but what I need isn’t printable! :rofl: :rofl: :rofl:


1 Like