2dom / PxMatrix

Adafruit GFX compatible graphics driver for LED matrix panels
BSD 3-Clause "New" or "Revised" License
828 stars 170 forks source link

Somehow displaying multiple images causes ESP8266 HTTP client to refuse connection #217

Open bfrizbee opened 4 years ago

bfrizbee commented 4 years ago

Device Info

Board: LOLIN(Wemos) D1 R2 & mini -- I have the D1 mini Upload Speed: 115200 Frequency: 80MHz Programmer: AVRISP mkII

Arduino IDE p.2 64x64 LED display

Issue

When looping through and drawing an image on the display, when using multiple images, any HTTP client calls get a connection refused error message. If only displaying 1 image type, http(s) calls are fine.

Slightly more in depth explanation: Images are a uint16_t static array. When referenced directly or pointer passed into method to display them (Signature: (uint16_t *frame) ), will cause HTTP to fail if more than one image is referenced. If only one is referenced, it works fine.

CODE:

Simple code that shows the problem is available here: https://github.com/bfrizbee/mypxmatrixissue/blob/master/pxMatrixIssue/pxMatrixIssue.ino

To Run, put your wifi SSID and password in the appropriate vars, and compile/upload to ESP8266.

Serial output will tell you that the HTTP code is -1 - Which is connection refused

If you change line 621 to banana_frame_1 or comment it out and recompile/upload, the HTTP code will be 200 (OK).

I have literally no idea why this happens, as I had run into it in my more complicated program. Thats why I borrowed witnessmenow's simple example and modified it to this.

Serial output

When bad

...Connected
HTTP CODE: -1

When Good

..Connected
HTTP CODE: 200
bfrizbee commented 4 years ago

can anyone help?

xsrf commented 4 years ago

Have you tried running a local http server and requesting data from it so you can actually monitor what the http request looks like e.g. using Wireshark? I guess there is not even a TCP connection established...

Edit: Also please make sure to add IRAM_ATTR before all functions executed by the Ticker, because they have to be in RAM. So, use IRAM_ATTR void display_updater().

bfrizbee commented 4 years ago

@xsrf Sorry it took me a little while, I had to figure out what the hell I was doing. I have never used wireshark before and apparently the portable install doesn't do any of the stuff that I needed (found out the hard way). Anyway I couldn't record the packets from the ESP8266 to google as I didn't have wireless on my computer/whatever the heck I needed to do to setup on windows, so I setup a simple express server on my desktop that would return a simple JSON response. It worked well as the refused connection error still shows up on the ESP8266 Watching the packets shows that there were packets being sent/received by my computer, though I'm not good with networking so I don't know much about it. Please let me know if you need more detailed information/how to obtain from this:

.10 is the ESP8266 and .9 is my computer

snip

EDIT: I had also put a console.log in the express route so when it is used I would know. The request from the ESP8266 with the connection refused never hits the route/fn to return the response

xsrf commented 4 years ago

First of all: Wow, great you went through all this and learned something new. I didn't expect that from someone who never used Wireshark or something familiar. All packets shown in the capture have a length of 0, so no actual data was transmitted. No request from the ESP and thus no response from your server. I guess there may be an issue with RAM? When the compiler sees that you're never using banana_frame_2, it will remove it entirely, so less RAM is used. Does it work with both images when you reduce them both to 64x32?

bfrizbee commented 4 years ago

Well I am a software engineer :). However networking has always been something I hated. The only networking class I had taken in college because it was required the teacher was kinda bad, and literally threw us into sockets in C when 90% of the class had never used C before... that didn't help. I had of course learned the basics of packets and everything but I don't remember almost any of it since I have never used it outside that class.

Back on topic: When I reduced the images to 64x32 it does indeed work as you suspected. I am somewhat surprised, as the compiler tells me at least:

Sketch uses 410192 bytes (39%) of program storage space. Maximum is 1044464 bytes.
Global variables use 42956 bytes (52%) of dynamic memory, leaving 38964 bytes for local variables. Maximum is 81920 bytes.

I know this isn't RAM per se, but I would think it would only load stuff into RAM as needed and not all at once. And it isn't as if the images wont display doing this, but the http connection won't send any data (apparently), which also makes almost no sense to me how they are related.

xsrf commented 4 years ago

So, I can reproduce the problem. It does work with either #define PxMATRIX_COLOR_DEPTH 2 or WiFiClient instead of WiFiClientSecure. Both also reduce the RAM usage. You can try putting your images into PROGMEM and reading them when you need them. I guess the WifiClient fails to allocate enought memory that would contain the Request-Body and TLS data, thus it fails to send a proper request. I can't see a Problem with PxMatrix in general though... The compiler only knows about static RAM usage. A lot of functions actually allocate memory dynamically at runtime when they need it and free it after usage - like the WiFi Client.

bfrizbee commented 4 years ago

Yea, from what you were saying, it seems more like an ESP8266 code issue. I will have to create an issue on their github and probably link this discussion so they have a background.

Also, I'm afraid I burnt out part of my D1 mini w/ESP8266 as I accidentally put it in its shield 1 pin up from what it is supposed to be (did it in the dark because I was messing around last night) and powered it through the shield. In doing so screwed something up :(. The light no longer blinks when connected/uploading/processing and I don't know if I can get any output to my led display. However, all code still processes fine/outputs fine according to serial monitor.

bfrizbee commented 4 years ago

Also unfortunately I have to use WiFiClientSecure since what I'm doing in my actual sketch is to query some APIs (of google and twitch) and display that data, so those both require https connection. I tried using PROGMEM and that does seem to work... now I just have to wait a month or two for my new esp8266 to come from china ;_;