Open Kuratius opened 1 year ago
Nevermind, this might just be a startup/flashing sequence. Still, it's probably possible to figure something out. I'll see if I can find any more information.
https://www.youtube.com/watch?app=desktop&v=MsbiO8EAsGw This seems to work with IL0373, so some of it may be relevant.
parsing the LUTS from the pimoroni driver gives this under the assumption that the voltage value is signed note that this may still be a wrong way to interpret the voltage it doesnt help that half the LUTS are identical
It seems like this is purely a LUT issue, and has been done by other people before
Seems to be sold as a greyscale display, maybe some of the sample codes contain a waveform that can be copied
Technique for getting 2 extra gray levels (total 4): Drive display to white with BW waveform
Lie to display about previous state Drive some pixels to black using WB waveform to update Pixels that remain white should use BW to update. Insert BB and WW waveforms that have adjusted timings, but not voltages (due to unknown format), use BB to drive white pixels gray shade 1, WW to drive black pixels gray shade 2.
More should be possible if waveforms can be changed on the fly, but will obviously take very long to update. Ideally you'd want to never drive pixels to white/black if they are already that color, but that makes things a bit more complicated. Since the BW/WW waveforms are identical, I interpret this as them being originally intended for refreshing the display from an unknown or random state.
I am not familiar with the codebase for this driver, but the driver used in the micropython project linked on the goodereader page seems to transmit the previous screen state before triggering a refresh, so I would assume this one should or could be made to work similarly.
This driver is based on the original release of the pimoroni C driver. There was a rewrite started before I had finished porting, but it didn't appear to have any useful changes. I have no idea how this development relates to the python driver. Are they doing a partial refresh somehow? I would have expected an inverted version of the current image in that case...
def EPD_init():
EPD_W21_Init() #Electronic paper IC reset
EPD_W21_WriteCMD(0x04)
lcd_chkstatus()#waiting for the electronic paper IC to release the idle signal
EPD_W21_WriteCMD(0x00) #panel setting
EPD_W21_WriteDATA(0x1f) #LUT from OTP£¬KW-BF KWR-AF BWROTP 0f BWOTP 1f
EPD_W21_WriteCMD(0x61) #resolution setting
EPD_W21_WriteDATA (0x80) #128
EPD_W21_WriteDATA (0x01) #296
EPD_W21_WriteDATA (0x28)
EPD_W21_WriteCMD(0X50) #VCOM AND DATA INTERVAL SETTING
EPD_W21_WriteDATA(0x97) #WBmode:VBDF 17|D7 VBDW 97 VBDB 57 WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7
#display
def PIC_display(picData):
#Write Data
EPD_W21_WriteCMD(0x10) #Transfer old data
for i in range(4736):
EPD_W21_WriteDATA(0xff)
EPD_W21_WriteCMD(0x13); #Transfer new data
for i in range(4736):
EPD_W21_WriteDATA(picData[i]) #Transfer the actual displayed data
#Refresh
EPD_W21_WriteCMD(0x12) #DISPLAY REFRESH
utime.sleep(0.01) #!!!The delay here is necessary, 200uS at least!!!
lcd_chkstatus() #waiting for the electronic paper IC to release the idle signal
#Clear screen
Relevant section
Thanks! Looking at the data sheet, this does appear to be for partial refresh - in black+white mode you send old data with command 0x10 (dtm1), new data with 0x13(dtm2). It's less clear about what to do next - it looks like you should send data stop command 0x11(DSP) but the python calls display refresh 0x12 (DRF)
Actually later in the datasheet they use DRF so perhaps that is the intended order of operations. I haven't looked at the rust code for a while so can't remember what we do...
I had a quick go at getting fast update mode going - it's not working correctly yet. https://github.com/9names/uc8151-rs/commits/fast_update
Reading through the datasheet, I forgot that I haven't really implemented any of the read commands, so I made a start on that as well, since we should check the status at least on Data Stop (DSP)
Ah. Read commands are wasted on badger2040 - even though MISO is on the schematic, it's not connected to the display. Well that was a waste of time :/
is this the same on the 2040w?
If you happen to have any tools that can measure the reflectivity of the display with good time resolution (high fps camera, or a photodiode hooked up to an oscilloscope or rpi) it may be possible to fit a model to the display so that waveforms don't have to be tested manually to see the the result.
e.g. a graph like in this paper + equation of motion (EOM) + some simplified model for the reflectivity
you get stuff like this.
Fascinating. I do not have fancy tools for measure reflectivity, pi/pico + photodiode would be the best I could do.
Speaking of cool e-ink stuff, you seen this? https://github.com/Modos-Labs/Glider I don't think it helps us at all, but the existence a 60/120hz e-ink display blows my mind.
It is not too surprising, but it will probably draw a lot of power. 2x refresh rate should be 4x power use, for very fast refreshes I expect it could go up to 16x. So only really interesting for stationary displays. Eink displays are essentially very weird particle accelerators, so there isn't a direct limit as long as you have power and uniform particles (and keep track not to make them clump together at one end).
Past a certain speed there may be some fluid flow effects that are hard to predict, but that just means you need better modeling. It is not a speed limit.
You need to move the black pigment a specific distance s in time t to achieve a color change. Meaning a velocity v=s/t
We know from stokes law that for spheres F=6π eta R v Electric force on a charged particle is qE
E is voltage/distance so
qE=6π eta R v qV/s=6π eta R s/t
V=6π eta R s^2/(qt). t=1/framerate (let's call it f) so V=6π eta R s^2 f/q
So for double the framerate you would expect double the voltage.
Also typically power draw scales with the square of the voltage, so you would expect that 2x voltage means 4x power draw.
The other thing to consider is that Stokes Law is an approximation for low velocities, you would expect that for high velocities it is invalid and you may have a quadratic relationship between force and velocity, so your voltage may scale with s^3/t^2, (meaning double the framerate is now 4x the voltage and 16x the power draw)
You can also work with reduced contrast + more opaque fluid to reduce the distance particles need to move.
https://github.com/sqfmi/badgy/tree/master/examples/grayscale
Might be interesting, will need to check if the lut tables are compatible. Posting so I don't forget.
Display seems the same size as the badger, no idea if it is actually the same.
https://github.com/antirez/uc8151_micropython Seems that someone has already implemented it.
It seems that the LUTs can be modified, and to my understanding greyscale is just a very advanced type of ghosting. https://github.com/adafruit/Adafruit_CircuitPython_UC8151D/blob/main/adafruit_uc8151d.py
The adafruit version of this driver seems to include some sort of grayscale LUT already, although I havent tested it.