Another Blade Runner thread: The Portable Voight-Kampff Scanner

I think you may have to make more than ten judging by all of the interest lol

I'm interested too, maybe a kit version with everything needed would be a good idea to save you some time, and maybe give all of us a bit of fun in assembling it

Also, I think you said in a prior post that you wish you had a CNC or something to make the frame for the pop up mechanism out of metal. Do you think you could do it by hand? The part is so small and thin that a hacksaw and some files may go a long way

OK, so, I'm absolutely going to put an interest thread up shortly to consolidate the folks who might want in on an run. I'll figure out the logistics and details there - I'm sure I'll lose some folks once I come up with a price for a fully-finished item, as it'll be into the low hundreds range, but c'est la vie. The folks who have bought stuff from me before know I do my best to under-promise and over-deliver. :cool

Unless... wait, I think by saying that I do that, I'm not actually under-promising at all, am I!?



A kit version is possible, is all I will say for now. I'll leave that for discussion in the interest thread once it gets made.

Anyway, with regard to your other question - I could probably do that by hand out of actual metal and a hacksaw-then-jeweller's-saw setup, but I think I will go absolutely (Roy) batty if I had to do that en masse. My solution is hopefully going to be much simpler: I have a laser cutter. It is not powerful enough to cut metal. It is powerful enough to cut plastics and acrylics. I would likely be cutting the 'metal' mechanism out of layers of plastic, then gluing/screwing them together (there are conveniently some small screws actually on the screen used prop which I expect I will use to hold things together). Then I'll paint them as convincingly silver as I can.

I sometimes get access to neat toys at the local university, but I don't think they have anything that would fit the bill otherwise. I'd be looking at something like a non-CO2-laser, a water-jet cutter, or a plasma cutter to get through even basic metal sheets. One day, I will have a bigger workshop and access to those kinds of toys. For now, I have to make do!
 
.

Looking forward to an unfinished kit with all the external "body parts".
Print it and throw it all into a bag.
Hopefully it will be hollow when assembled. :)
 
daniel here; first post! :) the reason why i made an account here to the RPF was because of this exact prop, i've been a fan of the rpf for ages, but barely made an account! anyhow im super interested Ein to have one as well; i love what you doing with the project, you are so talented! by the way i watched the movie 4 times already! love it!
 
Last edited by a moderator:
Thought you might find this concept art interesting.
mike-hill-k-eye-scanner-mike-hill-blade-runner-2049.jpg
 
I happen to think that design is way more interesting than what they ended up using in the film. That said, the added complexity of two pop-out elements is probably more than enough of an explanation as to why they went with a much simpler design. I'll probably still steal the button labels from the concept, though ("Alt", etc).
 
Yep... I'm thinking this is the right screen.



The actual viewable area is a good fit for what I need, and I'll be able to hide the rest behind the plastic... should be possible to cut the top end of the PCB off entirely. Going to settle in and figure out how this one works.
 
the screen will give it a more realistic look, besides you could hide graphics in there only accessible through button-pressing combinations! (a lá Mortal Kombat in the 90's hehehehe)
 
This project seems to be moving right along :)

If a kit of parts does become available for purchase, I think instead of making mine to resemble the movie version in functionality
(with the thin back lit panel as the screen), I will build mine to be useful to me so it doesn't just sit on a shelf with no real purpose.
I think I will use a simple, inexpensive, MP4 player and use it to listen to the radio or my own playlist with an ear bud.

My prop screen functionality would have no "real purpose" other then finding my music preference.
The pop up feature in this prop seams odd to me anyway since it tends to reveal bare electronic components and LED scanning light (which could have just been placed in the case, on the side), but I guess it has that cool factor in the movie. It doesn't even reveal push buttons.

Since this prop will be designed to pop up anyway, this will give me a place to put the small tactile switches on the back to activate my MP4 player.

Looking forward to the completion and availability. Keep up the good work. :)

.
 
Last edited:
Not sure if this will happen, but if the body of this scanner does become available for purchase, I am working on the electronics I think I will use.

Here is another short video of my progress:
I know it is not an actual replica electronics setup, but I think for me, it does the job nicely :)





.
 
Last edited by a moderator:
So, I have been forging ahead with this, despite my lack of posts over the last few days. I did say I was going to be exhaustively thorough about this, so it's time for me to make good on that. This is going to be focused on the nitty-gritty technical details. Almost all of my Saturday was spent trying to get the new screen to behave. I've learned a lot over the last weekend about exactly what I'm doing when it comes to these displays. I'm going to share what I've uncovered so far, mostly because I've been finding the process interesting.

DRAW SPEED

There are plenty of compatible libraries that can turn the screen on and display graphics without issues, but they tended to be sloooow. I discovered one bottleneck was the fact that my arduino was in what's called "Software SPI" mode; SPI stands for Serial Peripheral Interface, and is sort of the language the Arduino uses to "talk" to other devices. "Software SPI" is also known as "bit banging", which is a great name for anything. The best summary I can give right now is that it involves making the microcontroller in the arduino do a lot of the heavy lifting before it sends the data to the screen. This is nice for compatibility, as you can have the microcontroller handle things like timing, but it also slows everything right the hell down, as you end up using CPU cycles on the microcontroller that could be better directed towards other functions. On something like a PC CPU, it'd hardly matter, because we're talking about zillions of calculations per cycle; on a tiny little Arduino, it's a visible dip in performance.

Fortunately, there is a "Hardware SPI" implementation for almost all of these setups, which seems to basically involve trusting the display to figure out a less-sanitized and prepared input. This runs three to five times faster from what I've seen - it's the difference between watching a screen slowly fill with a color, and doing it instantly. It took some figuring (and some soliciting help on the official Arduino forums) but I've got the setup figured out and running smoothly now. Everything works, and nice and fast! Hooray! On to the next challenge...

TAILORING THE SCREEN

The screens I have been working with are actually pretty awesome. They have a great color range, controllable backlight, and they actually each come with SD card holders on the backs. However, there are design limitations posed by the Voight-Kampff device itself. In order to use the SD card functions on this board, you have to wire to the appropriate pins. The "appropriate pins" in this case are at the top of the board:



If you look at the design of the VK, you'll see that the screen itself is pretty close to the top of the 'base' unit - almost flush along the top, really - which means that this red circuit board would be sticking out once the pop-out component extended. That's no good. That'd ruin the look of the prop.

Fortunately, if we take a look at the back of the board, the SD card reading elements are totally isolated from the rest of the board.



Another thing to consider is that the SD card reader itself is actually a pretty big component. The screen itself is surprisingly thin, but the SD Card enclosure is nearly the width of the rest of the unit again!



In light of all of the above, it's clear: The SD card stuff has to go. Thanks to the way the board is designed, this is totally doable! Step one is to take a soldering iron and some solder wick/ solder braid to start desoldering the SD card holder. You heat the iron up and press the solder wick between the hot tip of the iron and the pad you are attempting to remove the solder from. The solder softens and flows into the copper weave of the wick, which you can then pick up. 90% of the solder holding a joint will come with the braid when you do that. Do that to each of the pads holding the SD card connection down and you can start to pry it up and off the board.



The whole thing ultimately came off pretty cleanly.



The top row of the PCB had to be removed, which was easily done with a dremel and a cutting wheel.



After all that, the moment of truth is whether or not the screen still works. I'm happy to report...



Yep, still good! On to...

THE MEMORY LIMITS

Both the Arduino Uno and the Pro Trinket have reasonable memory limits by Arduino standards - the Uno maxes out at 32256 bytes and the Pro Trinket at 28672 (though you can get more out of it, I'll touch on this later). I'm going to be using the Pro Trinket for this project largely because it has a super-small footprint, can run off 3 volts (and is therefore LiPo-battery friendly), and it's cheap.

Realistically, it should be totally possible to use the SD card as extra memory for all of the possible graphics I'd want to display. Only... well, ****. We just removed that because we needed the screen to fit inside the VK better. What do we do?

The best answer I have is that we draw it all by hand using our various graphics primitives functions. It's difficult and tedious, but it also takes the absolute least amount of memory on the arduino.

To highlight an example, I'm going to use this grid design with an eye.



Simple enough, right? The TFT graphics libraries can draw bitmaps. But wait - a 24-bit bitmap like this takes 44,100 bytes to store. This is far more than the 28672 the entire device has available, and that's just for a 121x121 pixel image to display on a 240x320 pixel screen. ****. What can we do?
Well, we can lose color data completely. Take it to grayscale. Save it as an 8-bit bitmap.



That knocks us down to 15928 bytes. Enough to get in memory? Sure. But enough to get in memory and do anything else useful? Not really.

What if we go all the way down to monochrome? A 1-bit bitmap - pixels are either on or off (black or white). Photoshop (or similar programs) have dithering algorithms to try and process this change in a sensible way. What are we working with then?



We're down to 2000 bytes. That's far more manageable, isn't it? Maybe a bit rough looking, but fortunately the tech we're seeing in Blade Runner 2049 still has some analog flairs that suggest that maybe we can get away with this. The graphics functions that draw this out on the screen can accept color parameters, so you can print the entire image in whatever color you want:



That's all well and good - but what about the actual UI elements? Surely the whole screen being the same color is going to look a bit... garbage? It is - so let's take the UI elements off the image and come up with a way of drawing this.



The graphics libraries have a couple of ways to do this - you can draw multiple individual lines from Point X1Y1 to Point X2Y2 to establish your grid, but that would require 14 lines of code, i.e.:


tft.drawLine(startX,startY,endX,endY,COLOR);
tft.drawLine(startX,startY,endX,endY,COLOR);
tft.drawLine(startX,startY,endX,endY,COLOR);
tft.drawLine(startX,startY,endX,endY,COLOR);
... and so on.


This works, but these kind of line-by-line declarations are not exactly memory-efficient in terms of space on the Arduino. We can do better. We can, in fact, utilize the tft.drawRect() method to draw some rectangles, and set a quick function up to run through the logic of drawing 49 separate, offset rectangles:


Code:
void drawEyeGrid(int xPos, int yPos, int16_t color){
  //set up initial grid; iterative rectangles, 6x6
  for(int y = 0; y<6; y++){
    for(int x = 0; x<6; x++){
      tft.drawRect(xPos+20*x,yPos+20*y,21,21,color);
    }
  }
  //highlight each corner with a white pixel for aesthetics
  for(int y = 0; y <= 6; y++){
    for(int x = 0; x <= 6; x++){
      tft.drawPixel(xPos+20*x, yPos+20*y, WHITE);
    }
  }
}


So that when we call a functon - drawEyeGrid(10, 50, MEDBLUEUI); - it draws our grid out in near-instant fashion. I set it up with an X and Y coordinate variable so we can move the grid around on the screen to wherever we may ultimately want it.


Great. Now how do we get the eye to show underneath that? The first step is to take our monochrome image and convert it to a byte array. That sounds complicated, but it actually isn't - there's a great online tool for exactly this. We upload our image, ask it for arduino-format code, and like magic, it takes our graphic and figures out a suitable byte array. This...



... gets turned into this:


Code:
const unsigned char eyeGraphic [] PROGMEM = {
    0x57, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0x77, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x54, 0x44, 0x00, 0x02, 0x45, 0x45, 0x7f, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xfd, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xf7, 0xfd, 0x55, 0x54, 0x40, 0x00, 0x05, 0x04, 0x57, 0x77, 0xff, 0xff, 0xff, 
    0x77, 0x77, 0x75, 0x55, 0x55, 0x55, 0x55, 0x11, 0x55, 0x55, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xdf, 0x77, 0x54, 0x44, 0x44, 0x00, 0x04, 0x04, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 
    0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 
    0xf5, 0x55, 0x54, 0x40, 0x00, 0x00, 0x40, 0x7f, 0x7f, 0x7f, 0x77, 0x77, 0xf7, 0x77, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x51, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x77, 0x57, 0x54, 
    0x44, 0x44, 0x44, 0x40, 0x47, 0xff, 0xff, 0xff, 0x7f, 0x5f, 0xff, 0x55, 0x55, 0x55, 0x55, 0x51, 
    0x55, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf7, 0x55, 0x51, 0x40, 0x40, 
    0x40, 0x40, 0x5f, 0xff, 0x77, 0x75, 0x77, 0x75, 0x57, 0x55, 0x55, 0x55, 0x45, 0x45, 0x55, 0x55, 
    0x55, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x67, 0x74, 0x54, 0x54, 0x14, 0x44, 0x44, 0x44, 
    0x7f, 0xff, 0x77, 0x55, 0x55, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x15, 0x15, 0x55, 0x55, 0x55, 0x7f, 
    0xff, 0xff, 0xff, 0xfd, 0x7f, 0xd5, 0x15, 0x41, 0x54, 0x54, 0x40, 0x00, 0x04, 0x00, 0x77, 0x77, 
    0x57, 0x57, 0x55, 0x55, 0x55, 0x15, 0x55, 0x55, 0x51, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 
    0xf7, 0x77, 0x77, 0x54, 0x54, 0x04, 0x50, 0x40, 0x44, 0x44, 0x44, 0x47, 0xfd, 0x75, 0x55, 0x55, 
    0x45, 0x55, 0x54, 0x55, 0x15, 0x45, 0x45, 0x55, 0x15, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff, 0xd4, 
    0x55, 0x41, 0x55, 0x35, 0x05, 0x00, 0x00, 0x40, 0x40, 0x4f, 0x77, 0x55, 0x55, 0x55, 0x15, 0x55, 
    0x51, 0x54, 0x55, 0x14, 0x15, 0x54, 0x55, 0x55, 0x5f, 0xff, 0xf7, 0xf7, 0x76, 0x74, 0x44, 0x00, 
    0x40, 0x44, 0x40, 0x04, 0x40, 0x40, 0x44, 0x55, 0x55, 0x55, 0x55, 0x54, 0x51, 0x55, 0x05, 0x51, 
    0x50, 0x50, 0x55, 0x45, 0x45, 0x55, 0x7f, 0xff, 0xf7, 0x55, 0x54, 0x50, 0x44, 0x40, 0x00, 0x41, 
    0x41, 0x40, 0x00, 0x00, 0x04, 0x75, 0x55, 0x55, 0x55, 0x51, 0x51, 0x54, 0x05, 0x45, 0x41, 0x01, 
    0x55, 0x14, 0x55, 0x55, 0xff, 0x77, 0x77, 0x54, 0x42, 0x44, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 
    0x40, 0x44, 0x45, 0x55, 0x55, 0x55, 0x55, 0x45, 0x45, 0x50, 0x00, 0x00, 0x00, 0x15, 0x11, 0x45, 
    0x55, 0x57, 0xff, 0xf5, 0x55, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x40, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x04, 0x40, 0x01, 0x11, 0x50, 0x00, 0x00, 0x14, 0x55, 0x55, 0x5f, 
    0xf7, 0x75, 0x44, 0x44, 0x00, 0x00, 0x13, 0x73, 0x60, 0x00, 0x00, 0x00, 0x44, 0x44, 0x55, 0x55, 
    0x55, 0x55, 0x50, 0x10, 0x11, 0x67, 0x45, 0xc4, 0x40, 0x01, 0x05, 0x15, 0x55, 0x5f, 0x75, 0x54, 
    0x44, 0x00, 0x00, 0x16, 0x4e, 0xdb, 0x41, 0x00, 0x00, 0x04, 0x04, 0x44, 0x55, 0x55, 0x55, 0x55, 
    0x00, 0x05, 0x1c, 0x9d, 0x15, 0x14, 0x00, 0x00, 0x11, 0x55, 0x55, 0x77, 0x57, 0x44, 0x40, 0x00, 
    0x1f, 0x1d, 0x18, 0x64, 0x40, 0x70, 0x00, 0x04, 0x44, 0x45, 0x55, 0x55, 0x55, 0x40, 0x00, 0x7f, 
    0x31, 0x50, 0x50, 0x11, 0x50, 0x00, 0x11, 0x55, 0x57, 0x75, 0x54, 0x40, 0x00, 0x01, 0xff, 0x10, 
    0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x44, 0x55, 0x55, 0x55, 0x50, 0x00, 0x51, 0xf4, 0x45, 0x40, 
    0x00, 0x01, 0x00, 0x00, 0x15, 0x55, 0x57, 0x54, 0x44, 0x40, 0x04, 0x40, 0x44, 0x44, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x04, 0x44, 0x55, 0x55, 0x55, 0x00, 0x11, 0x45, 0x44, 0x00, 0x00, 0x00, 0x14, 
    0x00, 0x00, 0x55, 0x55, 0x55, 0x54, 0x40, 0x00, 0x72, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x54, 0x55, 0x55, 0x40, 0x01, 0x64, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 
    0x05, 0x55, 0x54, 0x44, 0x00, 0x17, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 
    0x05, 0x55, 0x54, 0x00, 0x55, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x54, 0x55, 
    0x54, 0x40, 0x01, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x55, 
    0x40, 0x05, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x54, 0x44, 0x00, 
    0x17, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x55, 0x41, 0x00, 0x15, 
    0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x15, 0x55, 0x40, 0x05, 0x15, 0x00, 
    0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x40, 0x15, 0x55, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x54, 0x44, 0x40, 0x7f, 0x44, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x55, 0x55, 0x41, 0x51, 0x40, 0x00, 0x00, 0x00, 0x00, 
    0x04, 0x00, 0x00, 0x00, 0x50, 0x15, 0x55, 0x50, 0x03, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x50, 0x00, 0x55, 0x54, 0x01, 0x50, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x15, 0x54, 0x40, 0x04, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x04, 0x55, 0x40, 0x45, 0x00, 0x00, 0x55, 0x00, 0x14, 0x14, 0x44, 0x00, 0x00, 0x01, 
    0x40, 0x15, 0x54, 0x01, 0x40, 0x00, 0x01, 0x7f, 0x00, 0x10, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x05, 0x54, 0x05, 0x40, 0x00, 0x15, 0x57, 0x00, 0x50, 0x40, 0x00, 0x00, 0x00, 0x14, 0x01, 0x54, 
    0x44, 0x17, 0x40, 0x00, 0x57, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x45, 0x50, 
    0x15, 0x00, 0x01, 0x55, 0x7c, 0x01, 0x54, 0x00, 0x44, 0x10, 0x40, 0x05, 0x45, 0x54, 0x00, 0x44, 
    0x00, 0x05, 0xff, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x01, 0x55, 0x01, 0x40, 0x00, 
    0x15, 0x57, 0x74, 0x05, 0x40, 0x00, 0x40, 0x01, 0x40, 0x45, 0x45, 0x44, 0x07, 0x40, 0x00, 0x77, 
    0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x41, 0x40, 0x44, 0x44, 0x54, 0x15, 0x40, 0x05, 0x55, 0x7f, 
    0xd8, 0x15, 0x44, 0x05, 0x44, 0x05, 0x40, 0x55, 0x55, 0x40, 0x54, 0x00, 0x05, 0x7f, 0xff, 0xf8, 
    0x10, 0x00, 0x01, 0x04, 0x1f, 0x00, 0x45, 0x45, 0x41, 0x54, 0x00, 0x55, 0x77, 0x77, 0xf0, 0x15, 
    0x55, 0x55, 0x10, 0x55, 0x00, 0x55, 0x54, 0x01, 0x40, 0x00, 0x57, 0xff, 0xff, 0xf0, 0x00, 0x01, 
    0x00, 0x00, 0x7e, 0x00, 0x56, 0x44, 0x05, 0x40, 0x05, 0x55, 0x77, 0xff, 0xd0, 0x15, 0x55, 0x50, 
    0x05, 0x75, 0x01, 0x55, 0x50, 0x14, 0x00, 0x05, 0x7f, 0xff, 0xff, 0xf0, 0x11, 0x11, 0x00, 0x07, 
    0xfc, 0x00, 0x55, 0x50, 0x50, 0x00, 0x15, 0x77, 0x7f, 0xff, 0xd0, 0x05, 0x54, 0x00, 0x17, 0x74, 
    0x05, 0x55, 0x40, 0x40, 0x00, 0x57, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xf4, 0x04, 
    0x75, 0x45, 0x50, 0x01, 0x55, 0x57, 0x7f, 0xff, 0xd0, 0x00, 0x00, 0x01, 0x7f, 0x54, 0x05, 0x55, 
    0x15, 0x40, 0x05, 0x77, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x17, 0xff, 0xf4, 0x04, 0x75, 0x55, 
    0x41, 0x55, 0x57, 0x77, 0xff, 0xff, 0xd4, 0x00, 0x00, 0x57, 0xff, 0x54, 0x05, 0x55, 0x54, 0x07, 
    0x57, 0x7f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0x50, 0x05, 0x75, 0x55, 0x55, 0x55, 
    0x57, 0xff, 0xfd, 0xfd, 0xdd, 0x00, 0x15, 0xff, 0xfd, 0x50, 0x15, 0x55, 0x50, 0x1f, 0x5d, 0xff, 
    0xff, 0xff, 0xff, 0xfd, 0xdd, 0xff, 0xff, 0xff, 0x40, 0x05, 0x75, 0x40, 0x15, 0x55, 0x77, 0x77, 
    0x7f, 0xff, 0xfd, 0x55, 0xff, 0xff, 0x75, 0x50, 0x55, 0x47, 0x15, 0x04, 0x77, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x47, 0x55, 0x55, 0x01, 0x55, 0x55, 0x77, 0xff, 0x77, 
    0xff, 0xff, 0xff, 0xff, 0x75, 0x51, 0x55, 0x51, 0x55, 0x40, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0xff, 0xff, 0xf7, 0x40, 0x07, 0x55, 0x55, 0x75, 0x57, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 
    0x7f, 0x77, 0x55, 0x54, 0x55, 0x57, 0x57, 0x74, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
    0xff, 0x77, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x77, 0x75, 0x55, 0x55, 0x7f, 0xfd, 0xfd, 
    0x55, 0x54, 0x55, 0x75, 0x75, 0x5f, 0x45, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 
    0xf0, 0x55, 0x55, 0x55, 0x55, 0x55, 0x7f, 0x77, 0x57, 0x75, 0x57, 0x77, 0x77, 0x75, 0x55, 0x55, 
    0x57, 0x76, 0x77, 0x76, 0x57, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xf7, 0x77, 0x60, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x7d, 0x75, 0x55, 0x57, 0xff, 0x55, 0x55, 0x55, 0x55, 0x7f, 0x55, 
    0x57, 0x57, 0xff, 0x55, 0x5f, 0xff, 0xff, 0xff, 0xfd, 0x54, 0x57, 0x77, 0x57, 0x55, 0x55, 0x55, 
    0x57, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0xff, 0x55, 0x57, 0x57, 
    0x5d, 0xf7, 0xf5, 0xc4, 0x35, 0x46, 0x75, 0xf7, 0x7f, 0xff, 0xfd, 0x55, 0x55, 0x55, 0x55, 0x57, 
    0xd5, 0xd5, 0xd5, 0x57, 0x5d, 0x55, 0x55, 0x75, 0x77, 0x7f, 0xff, 0x55, 0x55, 0xd7, 0xdf, 0x7f, 
    0xfd, 0xdf, 0xd7, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xf7, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 
    0x57, 0x55, 0x57, 0x77, 0x75, 0x57, 0x77, 0x7f, 0xf7, 0x74, 0x54, 0x57, 0x74, 0x5f, 0x7f, 0x4d, 
    0x47, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xf5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x7f, 0xfd, 0x55, 0x55, 0x55, 0x55, 0x75, 0x55, 0x55, 0x55, 0xfd, 
    0xff, 0xff, 0xff, 0xff, 0x77, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0xff, 0x77, 0x57, 0x54, 0x54, 0x44, 0x55, 0x47, 0x77, 0x55, 0x77, 0x77, 0x77, 
    0x77, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 
    0x57, 0xff, 0xfd, 0x55, 0x50, 0x54, 0x54, 0x45, 0x55, 0x55, 0x55, 0x57, 0x55, 0x55, 0x77, 0x77, 
    0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x7f, 0xff, 
    0x77, 0x54, 0x44, 0x44, 0x44, 0x45, 0x44, 0x54, 0x57, 0x75, 0x57, 0x77, 0x77, 0xf7, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0x75, 0x55, 
    0x55, 0x55, 0x54, 0x55, 0x45, 0x55, 0x55, 0x55, 0x55, 0x57, 0xff, 0x77, 0x55, 0x55, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x77, 0xff, 0xff, 0x77, 0x54, 0x44, 0x44, 
    0x54, 0x45, 0x54, 0x57, 0x55, 0x57, 0x57, 0x7f, 0xff, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x77, 0xff, 0xff, 0x55, 0x54, 0x54, 0x54, 0x54, 0x55, 
    0x54, 0x55, 0x55, 0x55, 0x7f, 0xff, 0xf7, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x77, 0x7f, 0xff, 0x77, 0x77, 0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 
    0x54, 0x57, 0x7f, 0xff, 0xf5, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 
    0x55, 0x57, 0xf7, 0x7f, 0xff, 0xff, 0x75, 0x55, 0x55, 0x54, 0x55, 0x54, 0x54, 0x55, 0x55, 0x5f, 
    0xff, 0xff, 0x77, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x7f, 
    0x75, 0xff, 0xff, 0x77, 0x77, 0x54, 0x54, 0x44, 0x44, 0x44, 0x44, 0x54, 0x57, 0x7f, 0xff, 0xff, 
    0x7d, 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xf5, 0x77, 0xff, 
    0xff, 0x75, 0x75, 0x55, 0x54, 0x54, 0x40, 0x54, 0x55, 0x55, 0x7f, 0xff, 0xff, 0xf7, 0x77, 0x75, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x77, 0x57, 0x7f, 0xff, 0xff, 0x77, 
    0x75, 0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x77, 0xff, 0xff, 0xff, 0xff, 0x77, 0x55, 0x55, 0x55, 
    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5d, 0xf
};


I know this looks like a mess, but if you'd believe it, the whole thing takes ~1,800 bytes to draw. We need to set up a function that can parse this information, which I am basically stealing wholesale from the Adafruit GFX library - it reads the byte array, and based on the information contained in it uses the drawPixel() function at the X-Y coordinates of each pixel in the bitmap.


Code:
void drawBitmap(int16_t x, int16_t y,
 const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {


  int16_t i, j, byteWidth = (w + 7) / 8;
  uint8_t byte;


  for(j=0; j<h; j++) {
    for(i=0; i<w; i++) {
      if(i & 7) byte <<= 1;
      else      byte   = pgm_read_byte(bitmap + j * byteWidth + i / 8);
      if(byte & 0x80) tft.drawPixel(x+i, y+j, color);
    }
  }
}


Note that you can set the color of the bitmap as it draws, so we can combine all of this into the following lines:


Code:
drawBitmap(10,50,eyeGraphic,120,119,MEDBLUEUI);
  drawEyeGrid(10, 50, WHITE);

which produces our goal!



We can go a step or two further here if we want to. We can, for example, color the sclera of the eye white with a separate byte array, or color the pupil whatever color we want with yet another byte array. These are small and light enough in terms of memory that it's negligible in terms of the overall arduino program.

WHAT DOES ALL THIS MEAN?

In the interest of draw speed and memory efficiency, I will be hard-coding the visuals the display shows to the microcontroller, rather than loading them from external memory sources. This directs some of the design philosophy of the graphics themselves, because I will need to basically partition everything in terms of element and color. There's not going to be any anti-aliasing or shading on the graphics beyond halftone patterns because I can't spare the overhead for it, but in some ways I feel like that aids the aesthetics of this particular item.

It also means that once I start committing to a certain UI or display design, I have to really commit, because changing things down the line might require fully overhauling the code from the bottom up. Which brings me to the present, where I'm agonizing over what the UI for this thing should actually look like!

FIGHTING WITH THE DESIGN:

This is my current mock-up:



I'm trying to stick to a generalized scheme of blues, maybe a bit tan, with white and red for detail spots at the moment. I liked the look of the white grid of dots as a backdrop. I can make all sorts of tech-looking greeblies, but I think my real issue is I don't know what to fill the spaces up with that feels appropriate. For example, is a DNA helix silly? Probably not, given the context of the scanner, but it does feel a bit hokey.

I had a slightly more colorful take on it:



I also played around with a "startup screen", but I'm not really sold on it yet.



Feels a bit too 80s-Encarta-y to me. It probably would have worked for the original Blade Runner's aesthetic of 2019 (a.k.a. 80s as hell) but 2049 looks a bit more minimalist and modern to me.

Candidly, I don't feel like I'm great at UI design. Not really my niche. I'd love some input or feedback. I want to work the design out fully before I start getting in and coding it all together so that I don't end up redoing it a million times over. I don't feel like I'm getting a good "Blade Runner" aesthetic for this yet - more generic futuristic UI than anything. Looking at the Creativereview.co.uk article in particular, I think I have to back up and maybe try again from scratch to get the look right.
 
Last edited:
Candidly, I don't feel like I'm great at UI design. Not really my niche. I'd love some input or feedback. I want to work the design out fully before I start getting in and coding it all together so that I don't end up redoing it a million times over. I don't feel like I'm getting a good "Blade Runner" aesthetic for this yet - more generic futuristic UI than anything. Looking at the Creativereview.co.uk article in particular, I think I have to back up and maybe try again from scratch to get the look right.

I don't think you're giving yourself enough credit. I think the design is closer than you think it is. When I have some more time tonight I'll see if I can provide any input but this is looking incredible as is.
 
This thread is more than 4 years old.

Your message may be considered spam for the following reasons:

  1. This thread hasn't been active in some time. A new post in this thread might not contribute constructively to this discussion after so long.
If you wish to reply despite these issues, check the box below before replying.
Be aware that malicious compliance may result in more severe penalties.
Back
Top