Video synth workshop

This workshop with La Diagonale at UP Saclay is a simple circuit to begin playing with code and screen patterns. 

Here is the github: https://github.com/merlinmarrs/spaghettini-video-synth

Arduino Coding and Video Synthesis Workshop

Lean to code in C with Arduino, solder and assemble a custom printed-circuit board made in the Fablab, and make your own algorithmically-generated video art!

This workshop is inspired by the improvisational music of Live coding (https://fr.wikipedia.org/wiki/Live_coding) and the burgeoning minimalist Bytebeats movement (https://nightmachines.tv/bytebeats-tutorial).

Our video synthesis kit plugs in to the Arduino (https://www.arduino.cc/), a reprogrammable embedded micro-controller that can interact with the world through code, and uses the VGAX library (https://github.com/smaffer/vgax) to generate funky video.

Meet other creative technologists and sharpen your expertise in computer sciences and electronics soldering!

Here are some initial sketches :

The functionality that is important is :

-being able to select between different programs (with button and leds to indicate)

-to be able to take audio in and have it modify the patterns on screen

-to be able to change the colors on the go

-I have since phased out the brightness changeability but I could add an LDR easily ?

*******************************************************************************************

Because our lasercutter is not operational, I am trying to make this circuit with the vinyl cutter using 5cm wide copper tape. 

 

I am worried about the headers getting pulled out when plugging/unplugging. I will try adding some hot glue to fortify them. The other option is potting the circuit in resin but that would get messy and expensive. 

Errata:

-button too close to headers when glue is applied

-remember space for audio in jack plug 

-the two columns of headers for the Arduino should not be continuous, also unclear what is first and last pin. Also they should be SMD headers. 

-don’t mess with RX and TX pins on the Arduino. 

-make a version with VGA plug?

-add text but have it cut onto plastic not made from metal

-audio offset thing doesn’t work

I also want to think about expandability, how could people take this project further by themselves afterwards ?

-Having a knob  or two knobs / LDR connected to an analog in on the Arduino…

-Be able to control the program based on voltage control levels at an input. This could mean it could even be attached to the polyphonic synth !

 

***************************************************************************

Here is the next version called the Spaghettini:

-It respects the height of the 50mm wide copper tape I have on hand.

-It makes more sense for the audio in cable to plug in at the side and not interfere with the capacitive sensor. 

-It uses curvy lines just for the capacitive sensing functionality and straight elsewhere which feels honest. 

-It has the ability to modify the brightness of any of the three channels, one at a time. 

-It has a potentiometer for analog in in adition the capacitive sensor. 

-I’m experimenting with different patterns on the left portion.

-The sensor works with the Arduino library CapacitiveSensor 

And here’s what it looks like all plugged in ! (But I need to add hot glue to make it really usable)

 

Memory Experiments (continued)

I have two goals for this project:

  1. Finish the VGA video recorder board (with op amps, bias pots, bias for ADC) – DONE!
  2. Make a version of the vectorscope image modification series but with a raster system taking the following image as the input – DONE :

1. Finishing the VGA Video Sampler board

For the first goal, I need to correct that last board I made:

Errata:

-The gain pots for the op-amp don’t work.

-I mixed up VCC (3.3V) and VCA (5V) in several places. (I just replaced the PFET with the LDO and manually rewired)

-The “EN” text next to the ADC was in the wrong place. 

-I forgot to tie down the reset of 74HC590 with a 10K resistor.

-The 74HC04 is labelled backwards, I put inputs on the right and outputs on the left for some reason.

Things appear to work with these changes:

It takes some knob fiddling but I can get an input sine wave digitalized. One definitely needs an oscilloscope to see what’s happening though.

2. Vectorscope image series

I can either load the image into memory by playing it on a computer screen and capturing the pixels, OR, loading the image into memory with a microcontroller. I’m not sure how big I should make the image, and what dimensions, if I load the image. 

Here is the p5.js code to take an image (called p.jpg) and print the red pixel value into a text document (called OUTPUT) with a comma and space seperator :

let img;

function preload() {
img = loadImage('p.jpg');
}

function setup() {
createCanvas(img.width, img.height);
background(220);
image(img, 0, 0);
let writer = createWriter('OUTPUT.txt');

for(var y = 0; y < height; y++) {
for(var x = 0; x < width; x++){
let pix = img.get(x, y);
writer.write(pix[0] + ', '); // takes RED pixel info, adds a comma and a space
if(!(y==1-height || x==1-width))
{
writer.write(pix[0]); // don't put a comma if it's the last element of the list
}
}
}
writer.close();
}

And here is the Arduino code to take this color information and load it into the memory space (90×90 max as PROGMEM has max 8,192 bytes max):

byte myChar;

#define IMG_WIDTH 90
#define IMG_HEIGHT 90
//data size=900 bytes
const unsigned char img [IMG_HEIGHT*IMG_WIDTH] PROGMEM={
17, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 23, 23, 22, 21, 21, 22, 22, 21, 22, 21, 22, 21, 20, 21, 21, 23, 23, 23, 23, 23, 23, 24, 23, 25, 23, 24, 23, 25, 25, 25, 25, 25, 24, 25, 26, 24, 23, 25, 24, 23, 24, 25, 21, 20, 24, 24, 23, 20, 20, 21, 23, 22, 22, 22, 22, 22, 23, 23, 24, 23, 23, 23, 25, 23, 24, 24, 23, 24, 25, 23, 25, 25, 23, 25, 24, 24, 25, 28, 28, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 19, 35, 25, 32, 32, 26, 27, 17, 23, 27, 30, 33, 33, 35, 37, 35, 29, 30, 34, 37, 44, 26, 30, 65, 65, 57, 56, 55, 57, 59, 42, 38, 46, 38, 33, 40, 41, 43, 46, 35, 3, 0, 0, 0, 0, 1, 1, 0, 9, 49, 18, 0, 4, 0, 0, 0, 3, 2, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 3, 29, 231, 255, 245, 252, 250, 247, 248, 240, 245, 249, 255, 255, 255, 255, 255, 254, 254, 255, 255, 255, 255, 252, 252, 255, 254, 255, 254, 255, 255, 255, 254, 255, 255, 254, 253, 255, 255, 255, 255, 255, 71, 1, 1, 1, 1, 0, 15, 189, 244, 255, 223, 205, 216, 183, 191, 207, 210, 221, 234, 240, 233, 220, 215, 113, 138, 251, 225, 219, 223, 224, 169, 166, 201, 208, 217, 220, 196, 190, 181, 189, 181, 188, 193, 148, 149, 207, 171, 25, 0, 50, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 250, 245, 244, 253, 255, 255, 246, 240, 239, 231, 239, 234, 255, 255, 255, 249, 238, 234, 247, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 90, 0, 1, 0, 1, 1, 43, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 241, 229, 249, 255, 255, 255, 254, 249, 249, 248, 255, 251, 254, 254, 255, 242, 235, 241, 253, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 77, 0, 31, 240, 254, 249, 189, 170, 192, 190, 179, 202, 131, 12, 4, 0, 107, 226, 192, 54, 0, 11, 8, 2, 2, 146, 225, 204, 71, 0, 0, 65, 200, 206, 192, 194, 197, 185, 200, 255, 255, 255, 211, 24, 0, 1, 0, 1, 0, 8, 178, 255, 255, 243, 204, 194, 197, 198, 189, 209, 181, 25, 0, 0, 106, 217, 213, 96, 0, 6, 5, 7, 0, 126, 236, 199, 38, 0, 0, 84, 220, 208, 203, 205, 198, 210, 200, 225, 255, 255, 68, 0, 19, 226, 254, 219, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 190, 255, 255, 95, 0, 3, 0, 2, 0, 3, 0, 48, 253, 255, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 144, 255, 255, 80, 0, 62, 255, 255, 235, 24, 0, 0, 0, 0, 0, 3, 2, 0, 1, 2, 0, 1, 5, 3, 1, 1, 2, 4, 1, 0, 0, 1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 189, 255, 255, 105, 0, 1, 1, 1, 0, 3, 0, 65, 255, 255, 124, 0, 1, 0, 0, 0, 0, 0, 3, 6, 2, 1, 0, 0, 4, 3, 0, 3, 1, 1, 2, 1, 0, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 157, 255, 255, 85, 0, 45, 252, 255, 241, 31, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 1, 0, 0, 187, 255, 255, 102, 0, 2, 1, 0, 0, 2, 0, 94, 255, 254, 143, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 2, 3, 1, 0, 0, 0, 134, 255, 255, 69, 0, 48, 253, 255, 227, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 178, 255, 255, 119, 0, 1, 0, 0, 1, 2, 0, 66, 255, 255, 138, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 145, 255, 255, 84, 0, 49, 254, 255, 229, 19, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 0, 0, 0, 1, 1, 2, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 196, 255, 255, 110, 0, 0, 0, 0, 0, 2, 1, 54, 255, 255, 138, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 130, 254, 255, 76, 0, 39, 245, 255, 225, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 2, 1, 23, 233, 255, 255, 82, 0, 2, 1, 0, 1, 1, 0, 61, 255, 255, 124, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 142, 255, 254, 74, 0, 55, 255, 254, 246, 31, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 207, 255, 255, 116, 0, 2, 0, 0, 0, 1, 1, 99, 255, 255, 137, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 92, 255, 255, 83, 0, 32, 254, 255, 107, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 1, 0, 0, 2, 1, 0, 71, 231, 255, 79, 0, 3, 0, 0, 0, 5, 0, 68, 241, 193, 48, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 159, 255, 89, 0, 55, 255, 182, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 1, 1, 0, 4, 1, 0, 0, 5, 6, 0, 0, 0, 2, 3, 1, 1, 0, 1, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 3, 3, 0, 137, 255, 95, 0, 52, 255, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 0, 0, 2, 1, 1, 1, 1, 14, 41, 8, 0, 1, 1, 0, 0, 2, 7, 4, 0, 1, 2, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 0, 0, 173, 255, 80, 0, 40, 254, 238, 34, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 7, 5, 0, 0, 0, 1, 1, 0, 29, 124, 222, 255, 113, 0, 0, 0, 0, 0, 4, 0, 44, 174, 80, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 114, 255, 255, 75, 0, 44, 250, 255, 225, 17, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 3, 1, 5, 1, 2, 5, 6, 3, 1, 2, 4, 4, 4, 2, 0, 0, 0, 1, 0, 93, 255, 255, 254, 191, 1, 0, 0, 0, 0, 2, 0, 60, 255, 255, 101, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 1, 0, 0, 2, 0, 113, 255, 255, 87, 0, 47, 251, 255, 249, 36, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1, 1, 3, 3, 1, 1, 1, 3, 0, 1, 1, 0, 0, 0, 0, 1, 89, 255, 255, 255, 178, 0, 0, 0, 0, 1, 2, 0, 66, 241, 255, 139, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 67, 255, 255, 87, 0, 51, 245, 254, 235, 24, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 86, 255, 255, 254, 197, 0, 0, 0, 0, 0, 3, 0, 97, 163, 192, 142, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 1, 0, 1, 0, 1, 115, 255, 255, 77, 0, 68, 254, 255, 241, 29, 1, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 95, 255, 255, 255, 192, 0, 1, 0, 1, 0, 3, 0, 78, 237, 254, 114, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 118, 255, 255, 84, 0, 72, 255, 255, 251, 41, 0, 2, 0, 0, 1, 3, 1, 1, 0, 0, 3, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 0, 1, 2, 0, 71, 255, 254, 255, 160, 0, 0, 0, 0, 1, 3, 0, 26, 233, 255, 132, 0, 0, 2, 0, 1, 1, 2, 2, 2, 2, 2, 0, 1, 0, 1, 2, 0, 1, 2, 3, 3, 2, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 165, 255, 255, 83, 0, 77, 255, 254, 227, 17, 0, 0, 0, 0, 0, 1, 4, 2, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 51, 253, 255, 255, 158, 0, 0, 0, 0, 2, 0, 1, 54, 255, 255, 98, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 3, 3, 4, 2, 0, 0, 0, 0, 0, 0, 0, 139, 255, 255, 72, 0, 71, 255, 255, 229, 89, 66, 87, 83, 78, 90, 46, 0, 0, 0, 103, 142, 136, 145, 128, 162, 157, 122, 126, 127, 128, 127, 128, 130, 128, 128, 127, 127, 127, 126, 125, 106, 172, 255, 255, 255, 224, 30, 0, 0, 0, 0, 3, 0, 92, 255, 254, 135, 0, 46, 44, 8, 11, 39, 30, 25, 26, 34, 54, 45, 22, 39, 32, 28, 28, 26, 28, 27, 38, 14, 0, 4, 0, 5, 32, 37, 29, 27, 32, 25, 9, 169, 254, 255, 88, 0, 26, 227, 255, 255, 255, 255, 255, 255, 255, 255, 231, 36, 0, 61, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 254, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 116, 0, 0, 0, 1, 0, 20, 190, 255, 254, 250, 239, 255, 255, 181, 196, 255, 245, 240, 241, 248, 255, 247, 239, 253, 246, 245, 245, 242, 243, 243, 255, 173, 0, 0, 0, 100, 254, 255, 245, 243, 247, 246, 246, 250, 255, 255, 79, 0, 46, 245, 255, 255, 254, 255, 255, 255, 255, 255, 255, 190, 0, 163, 255, 255, 254, 255, 255, 255, 255, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 254, 255, 254, 255, 255, 255, 138, 0, 0, 0, 1, 0, 61, 255, 255, 255, 254, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 119, 0, 12, 222, 255, 255, 255, 255, 255, 254, 255, 255, 255, 249, 48, 0, 80, 255, 255, 237, 139, 113, 121, 128, 127, 123, 149, 83, 1, 92, 219, 207, 197, 173, 206, 190, 150, 183, 255, 255, 255, 221, 214, 199, 170, 170, 180, 189, 242, 255, 255, 255, 254, 255, 255, 255, 255, 131, 0, 0, 0, 1, 0, 58, 255, 254, 255, 255, 254, 255, 255, 172, 80, 103, 108, 175, 220, 199, 101, 141, 255, 255, 158, 74, 100, 96, 102, 107, 87, 109, 60, 0, 4, 104, 128, 109, 115, 114, 125, 108, 97, 209, 255, 255, 88, 0, 58, 255, 255, 157, 0, 0, 0, 0, 0, 1, 0, 0, 5, 1, 1, 0, 0, 1, 0, 1, 0, 10, 221, 255, 253, 48, 2, 1, 0, 3, 12, 83, 255, 255, 254, 255, 255, 255, 254, 249, 193, 35, 0, 1, 0, 1, 1, 0, 79, 162, 233, 255, 255, 255, 255, 129, 0, 1, 8, 14, 11, 6, 8, 85, 255, 255, 70, 0, 0, 1, 1, 0, 0, 1, 1, 7, 10, 2, 1, 0, 0, 0, 0, 1, 0, 115, 255, 255, 86, 0, 80, 254, 187, 0, 0, 0, 2, 1, 1, 1, 0, 2, 6, 1, 0, 0, 0, 1, 0, 0, 0, 23, 231, 255, 255, 60, 1, 0, 1, 98, 200, 251, 254, 255, 255, 255, 241, 154, 81, 9, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 6, 70, 183, 254, 255, 254, 189, 27, 16, 8, 0, 0, 5, 169, 255, 255, 86, 0, 1, 2, 3, 5, 4, 1, 1, 3, 5, 4, 4, 0, 1, 3, 1, 3, 0, 0, 169, 255, 90, 0, 88, 255, 179, 0, 0, 0, 0, 0, 1, 2, 4, 2, 1, 5, 5, 5, 1, 0, 2, 0, 1, 57, 255, 255, 255, 86, 0, 1, 137, 255, 255, 254, 255, 254, 209, 79, 11, 1, 0, 0, 1, 2, 0, 1, 0, 0, 1, 1, 2, 1, 1, 0, 0, 42, 168, 255, 255, 252, 152, 27, 1, 0, 14, 193, 255, 255, 88, 0, 2, 0, 2, 1, 1, 3, 6, 2, 0, 6, 4, 0, 1, 0, 0, 2, 4, 0, 150, 255, 89, 0, 64, 255, 255, 73, 0, 0, 0, 0, 2, 2, 8, 8, 0, 2, 4, 3, 1, 0, 1, 1, 0, 47, 250, 255, 255, 114, 0, 141, 255, 255, 255, 255, 247, 107, 0, 0, 1, 1, 2, 0, 1, 1, 0, 0, 1, 0, 0, 1, 2, 2, 0, 2, 1, 0, 0, 77, 244, 255, 255, 200, 22, 4, 12, 141, 255, 255, 87, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 33, 221, 255, 79, 0, 72, 255, 255, 201, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 34, 242, 255, 255, 90, 50, 255, 255, 253, 255, 220, 37, 0, 1, 9, 3, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 0, 4, 4, 0, 27, 208, 255, 255, 196, 24, 8, 62, 255, 254, 86, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 255, 255, 92, 0, 99, 255, 255, 227, 16, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 64, 255, 255, 255, 87, 145, 255, 255, 255, 214, 23, 0, 2, 2, 5, 5, 0, 2, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 5, 0, 8, 192, 255, 185, 5, 2, 80, 255, 255, 91, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 172, 255, 255, 93, 0, 105, 255, 255, 226, 16, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 52, 253, 255, 243, 131, 217, 255, 255, 235, 33, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 214, 207, 0, 0, 73, 254, 255, 89, 0, 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 173, 255, 255, 97, 0, 93, 255, 255, 221, 13, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 49, 252, 255, 253, 254, 255, 255, 255, 97, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 33, 239, 193, 81, 141, 255, 254, 93, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 168, 255, 255, 93, 0, 68, 255, 245, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 34, 242, 255, 255, 255, 254, 255, 139, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 113, 254, 255, 255, 254, 255, 94, 1, 3, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 191, 255, 94, 0, 69, 255, 185, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 228, 254, 255, 255, 255, 212, 15, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 5, 204, 255, 255, 255, 255, 88, 0, 2, 1, 1, 3, 2, 1, 5, 2, 2, 1, 1, 1, 1, 0, 0, 2, 1, 0, 153, 255, 95, 0, 92, 254, 179, 0, 1, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 254, 255, 255, 255, 255, 111, 0, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 0, 101, 255, 255, 255, 255, 94, 1, 0, 3, 2, 3, 4, 5, 7, 3, 5, 7, 5, 2, 0, 1, 0, 0, 5, 1, 163, 255, 93, 0, 102, 255, 241, 50, 0, 0, 0, 0, 0, 1, 0, 5, 4, 2, 0, 0, 0, 0, 0, 0, 0, 81, 255, 254, 254, 255, 233, 25, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 3, 1, 10, 216, 254, 255, 254, 86, 0, 0, 1, 0, 0, 0, 1, 2, 6, 6, 4, 0, 0, 1, 0, 0, 0, 1, 21, 220, 255, 87, 0, 72, 255, 254, 235, 163, 162, 167, 164, 164, 182, 89, 0, 0, 15, 192, 233, 211, 212, 212, 210, 236, 223, 242, 255, 255, 255, 164, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 0, 0, 125, 255, 255, 255, 169, 87, 118, 97, 98, 106, 124, 72, 0, 5, 0, 39, 152, 148, 142, 143, 141, 146, 132, 216, 255, 255, 94, 0, 81, 255, 255, 255, 254, 255, 255, 255, 255, 255, 246, 63, 0, 115, 255, 255, 255, 255, 255, 255, 255, 254, 255, 254, 255, 255, 67, 0, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 6, 0, 56, 255, 254, 255, 255, 255, 255, 255, 255, 254, 255, 255, 75, 0, 0, 165, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 98, 0, 87, 254, 255, 254, 255, 254, 255, 255, 255, 255, 255, 109, 0, 165, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 48, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 25, 232, 255, 237, 255, 244, 238, 255, 249, 248, 255, 254, 150, 0, 2, 212, 255, 255, 255, 255, 254, 254, 250, 252, 255, 255, 100, 0, 37, 224, 255, 173, 71, 81, 83, 70, 66, 70, 69, 20, 0, 81, 177, 148, 121, 117, 119, 116, 116, 119, 116, 118, 128, 82, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 3, 2, 0, 25, 36, 15, 41, 23, 18, 46, 31, 26, 36, 30, 10, 0, 0, 34, 55, 37, 40, 41, 41, 40, 8, 91, 234, 222, 57, 0, 0, 11, 12, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 3, 2, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 1, 0, 0, 0, 1, 1, 0, 0, 0, 2, 0, 3, 4, 3, 0, 0, 1, 4, 2, 2, 2, 1, 3, 2, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 3, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 3, 6, 1, 2, 1, 0, 0, 2, 5, 4, 0, 0, 2, 2, 0, 2, 10, 7, 0, 0, 2, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 4, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 8, 1, 5, 7, 2, 1, 0, 0, 0, 1, 1, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 1, 0, 0, 0, 0, 0, 5, 1, 1, 0, 6, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 4, 1, 0, 0, 0, 0, 0, 7, 8, 0, 0, 1, 0, 0, 0, 0, 0, 3, 56, 60, 8, 0, 1, 161, 252, 137, 40, 65, 62, 45, 46, 68, 68, 16, 0, 18, 97, 111, 100, 100, 95, 100, 111, 113, 108, 129, 137, 42, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 0, 11, 183, 217, 202, 207, 213, 221, 195, 189, 202, 211, 234, 99, 0, 0, 104, 182, 142, 141, 153, 141, 145, 126, 189, 255, 253, 45, 0, 18, 225, 255, 255, 255, 255, 255, 255, 255, 255, 255, 83, 0, 73, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 177, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 3, 0, 62, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 103, 0, 1, 164, 255, 255, 255, 255, 255, 254, 255, 254, 255, 251, 46, 0, 8, 210, 255, 255, 254, 252, 253, 255, 253, 255, 180, 2, 0, 0, 181, 255, 255, 254, 255, 255, 254, 254, 255, 255, 255, 233, 23, 0, 4, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 97, 255, 255, 255, 255, 247, 244, 241, 241, 244, 255, 156, 0, 0, 0, 34, 192, 208, 191, 190, 186, 186, 166, 218, 254, 249, 43, 0, 10, 225, 255, 119, 8, 26, 29, 28, 26, 28, 10, 0, 10, 1, 12, 57, 55, 52, 49, 36, 40, 35, 199, 255, 254, 255, 84, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 1, 0, 159, 255, 255, 255, 135, 1, 23, 22, 20, 22, 16, 3, 0, 7, 8, 0, 1, 0, 0, 1, 0, 0, 1, 74, 255, 255, 40, 0, 20, 248, 131, 1, 1, 0, 0, 0, 0, 1, 0, 3, 2, 4, 2, 0, 0, 0, 0, 0, 0, 0, 169, 254, 255, 255, 165, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 4, 1, 31, 240, 255, 255, 255, 117, 0, 1, 0, 0, 0, 0, 1, 3, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 136, 255, 46, 0, 21, 246, 124, 0, 1, 0, 0, 0, 0, 2, 1, 1, 2, 1, 4, 0, 0, 0, 1, 2, 0, 1, 184, 255, 255, 254, 255, 55, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 1, 0, 148, 254, 255, 255, 255, 118, 0, 0, 0, 1, 2, 1, 0, 2, 1, 0, 3, 2, 1, 0, 0, 0, 2, 6, 1, 124, 255, 45, 0, 16, 250, 156, 0, 1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 1, 0, 0, 0, 0, 1, 0, 194, 255, 254, 255, 255, 171, 0, 0, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 0, 40, 245, 255, 255, 255, 255, 121, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 0, 137, 255, 42, 0, 22, 240, 255, 93, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 196, 255, 255, 255, 255, 255, 80, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 137, 255, 255, 255, 255, 254, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 255, 255, 49, 0, 13, 219, 255, 148, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 255, 255, 255, 176, 202, 247, 31, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 64, 253, 255, 254, 255, 255, 255, 122, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 255, 250, 46, 0, 13, 222, 255, 113, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 1, 0, 190, 255, 254, 99, 0, 134, 255, 173, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 4, 0, 24, 248, 192, 40, 29, 128, 255, 255, 113, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 255, 255, 46, 0, 22, 227, 255, 138, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 188, 254, 197, 0, 54, 255, 255, 254, 153, 0, 1, 2, 2, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 2, 3, 0, 1, 2, 1, 4, 7, 0, 23, 217, 255, 200, 24, 0, 94, 254, 255, 126, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 142, 255, 245, 38, 0, 17, 233, 255, 103, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 191, 255, 212, 8, 24, 181, 255, 255, 255, 186, 20, 0, 0, 3, 4, 2, 1, 2, 2, 0, 0, 0, 0, 1, 0, 2, 2, 0, 3, 2, 1, 3, 1, 0, 48, 230, 255, 255, 254, 84, 11, 84, 255, 255, 132, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 98, 254, 254, 39, 0, 18, 248, 143, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 4, 209, 255, 255, 108, 5, 4, 123, 255, 255, 255, 235, 75, 0, 0, 3, 5, 0, 4, 4, 0, 0, 1, 1, 1, 2, 0, 4, 1, 2, 4, 2, 0, 0, 109, 255, 255, 255, 254, 111, 4, 11, 165, 255, 255, 116, 1, 1, 2, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 1, 0, 139, 255, 48, 0, 18, 245, 126, 0, 1, 0, 1, 2, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 183, 255, 255, 89, 1, 1, 6, 94, 239, 255, 254, 255, 186, 52, 0, 0, 1, 0, 6, 7, 0, 0, 0, 0, 2, 7, 6, 2, 0, 0, 0, 80, 211, 255, 255, 255, 179, 33, 8, 0, 5, 162, 254, 255, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 128, 255, 47, 0, 25, 255, 173, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 2, 1, 0, 0, 0, 0, 0, 1, 0, 200, 255, 245, 48, 6, 0, 2, 11, 15, 140, 252, 255, 255, 255, 185, 74, 0, 0, 0, 4, 2, 0, 0, 2, 5, 2, 0, 1, 7, 90, 201, 255, 255, 255, 255, 113, 9, 12, 0, 0, 5, 134, 255, 255, 123, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 143, 255, 44, 0, 31, 241, 255, 140, 7, 29, 33, 29, 14, 28, 32, 10, 0, 0, 51, 65, 51, 54, 54, 55, 36, 55, 227, 255, 235, 69, 142, 200, 122, 55, 1, 1, 189, 255, 255, 255, 254, 255, 227, 194, 108, 3, 0, 0, 0, 1, 0, 12, 102, 165, 228, 255, 255, 255, 255, 255, 123, 0, 9, 92, 135, 130, 52, 149, 255, 255, 137, 0, 19, 23, 24, 11, 0, 21, 9, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 80, 255, 255, 64, 0, 10, 213, 255, 254, 251, 249, 251, 247, 231, 249, 255, 107, 0, 32, 243, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 243, 240, 254, 255, 255, 255, 255, 254, 255, 254, 255, 65, 0, 0, 1, 0, 0, 121, 255, 255, 255, 255, 255, 255, 255, 255, 220, 213, 241, 251, 255, 255, 253, 252, 255, 255, 250, 233, 237, 239, 241, 228, 216, 254, 185, 0, 0, 132, 189, 164, 167, 156, 163, 161, 155, 228, 254, 255, 61, 0, 17, 221, 255, 255, 255, 255, 255, 254, 255, 255, 228, 37, 0, 0, 171, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 66, 0, 1, 0, 0, 1, 124, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 167, 0, 1, 176, 255, 255, 255, 255, 255, 255, 255, 255, 255, 199, 1, 0, 21, 229, 255, 172, 79, 95, 102, 99, 95, 106, 46, 0, 2, 0, 36, 133, 138, 128, 127, 130, 132, 136, 140, 142, 141, 145, 145, 140, 142, 154, 159, 147, 157, 157, 143, 143, 146, 220, 255, 255, 153, 0, 0, 0, 0, 1, 0, 16, 200, 255, 255, 211, 148, 182, 180, 192, 203, 193, 188, 194, 196, 192, 187, 196, 189, 194, 196, 177, 187, 194, 201, 206, 220, 192, 29, 0, 0, 45, 175, 173, 158, 165, 164, 163, 137, 209, 255, 209, 12, 0, 26, 237, 255, 108, 1, 0, 0, 0, 0, 0, 0, 7, 5, 5, 3, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 152, 255, 254, 55, 1, 3, 0, 0, 0, 5, 0, 99, 255, 255, 122, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 3, 7, 5, 2, 1, 0, 0, 0, 0, 0, 0, 122, 255, 251, 43, 0, 30, 238, 255, 113, 0, 2, 0, 1, 0, 2, 2, 3, 3, 1, 2, 2, 2, 2, 2, 3, 5, 1, 1, 4, 3, 3, 3, 3, 4, 1, 1, 3, 1, 1, 1, 0, 1, 185, 255, 255, 87, 0, 1, 0, 1, 1, 0, 0, 141, 255, 255, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 142, 255, 255, 57, 0, 19, 228, 255, 120, 1, 0, 1, 0, 1, 0, 2, 0, 0, 0, 1, 2, 1, 1, 1, 2, 2, 1, 4, 2, 0, 0, 2, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 163, 255, 255, 74, 1, 1, 0, 0, 2, 0, 0, 141, 254, 255, 114, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 2, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 147, 255, 255, 54, 0, 30, 238, 255, 121, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 142, 255, 255, 66, 0, 1, 1, 0, 0, 1, 0, 128, 255, 255, 105, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 152, 255, 247, 40, 0, 25, 232, 254, 119, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 174, 255, 255, 71, 0, 1, 0, 0, 2, 0, 0, 143, 255, 255, 106, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 153, 255, 250, 45, 0, 28, 235, 254, 142, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 190, 255, 255, 76, 0, 1, 0, 0, 0, 0, 0, 148, 255, 255, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 255, 248, 45, 0, 20, 244, 230, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 117, 255, 255, 75, 1, 0, 0, 0, 0, 0, 1, 145, 255, 255, 94, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 118, 255, 250, 38, 0, 40, 254, 117, 1, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 70, 146, 27, 0, 1, 0, 0, 0, 2, 0, 65, 197, 84, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 143, 255, 39, 0, 25, 253, 126, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 3, 2, 0, 0, 4, 4, 0, 0, 1, 0, 2, 4, 0, 0, 0, 4, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 121, 255, 43, 0, 27, 255, 137, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 1, 8, 25, 6, 1, 0, 0, 0, 0, 0, 4, 8, 11, 3, 2, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 114, 255, 52, 0, 39, 254, 255, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 23, 201, 237, 27, 0, 0, 0, 1, 0, 1, 0, 39, 240, 141, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 26, 206, 255, 45, 0, 37, 244, 255, 131, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 98, 255, 236, 27, 0, 2, 1, 0, 0, 3, 0, 34, 255, 255, 52, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 138, 255, 245, 39, 0, 37, 245, 254, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 95, 255, 244, 32, 1, 0, 0, 0, 2, 1, 0, 55, 255, 255, 46, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 117, 255, 248, 39, 0, 33, 242, 255, 117, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 114, 255, 230, 21, 0, 1, 0, 0, 0, 4, 0, 51, 255, 255, 53, 0, 2, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 118, 255, 251, 43, 0, 29, 239, 255, 115, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 114, 255, 237, 35, 0, 1, 0, 0, 0, 5, 0, 45, 255, 254, 51, 0, 2, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 125, 254, 254, 48, 0, 34, 242, 255, 116, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 3, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 109, 255, 242, 36, 0, 1, 0, 0, 1, 2, 0, 51, 254, 255, 56, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 0, 1, 124, 255, 246, 38, 0, 34, 245, 255, 111, 0, 1, 0, 0, 0, 0, 1, 0, 2, 2, 0, 0, 1, 4, 3, 7, 3, 2, 2, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 108, 255, 218, 7, 0, 0, 0, 1, 0, 3, 0, 44, 254, 255, 50, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 0, 0, 1, 3, 3, 1, 1, 3, 1, 1, 0, 1, 1, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 128, 255, 243, 36, 0, 40, 246, 255, 157, 9, 23, 32, 30, 17, 29, 13, 0, 1, 0, 24, 61, 25, 0, 1, 0, 0, 1, 0, 0, 34, 32, 0, 1, 0, 1, 12, 6, 0, 2, 19, 22, 0, 128, 255, 240, 36, 0, 2, 1, 1, 0, 1, 1, 64, 255, 255, 64, 1, 10, 7, 10, 10, 16, 6, 0, 0, 0, 10, 35, 13, 1, 0, 0, 0, 0, 0, 0, 6, 8, 0, 0, 0, 0, 3, 8, 6, 7, 8, 2, 0, 150, 255, 248, 43, 0, 27, 229, 255, 255, 247, 242, 246, 243, 233, 254, 216, 46, 0, 43, 217, 255, 242, 61, 0, 23, 11, 18, 0, 94, 255, 255, 102, 2, 6, 121, 253, 228, 215, 220, 241, 250, 176, 197, 255, 255, 204, 6, 1, 0, 0, 2, 1, 8, 214, 255, 238, 243, 222, 230, 223, 225, 226, 255, 150, 0, 0, 49, 217, 255, 189, 22, 18, 37, 36, 41, 22, 75, 228, 250, 83, 0, 1, 44, 203, 245, 227, 226, 226, 224, 223, 249, 255, 251, 46, 0, 23, 231, 255, 254, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 252, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 254, 255, 255, 255, 255, 241, 33, 0, 1, 0, 1, 0, 14, 224, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 254, 255, 253, 254, 255, 255, 255, 255, 255, 254, 255, 255, 255, 255, 244, 39, 0, 10, 122, 153, 147, 144, 138, 142, 134, 131, 131, 138, 145, 136, 124, 122, 125, 139, 148, 151, 158, 139, 129, 143, 40, 74, 144, 135, 128, 127, 106, 109, 116, 106, 102, 99, 110, 117, 114, 97, 129, 96, 0, 0, 0, 0, 0, 0, 0, 102, 138, 112, 123, 116, 117, 107, 114, 131, 132, 140, 135, 135, 130, 112, 137, 86, 86, 118, 105, 101, 100, 108, 94, 93, 101, 103, 119, 120, 105, 100, 103, 102, 101, 99, 97, 95, 89, 83, 63, 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// ARRAY OF PIXELS GOES HERE, COMMA + SPACE SEPERATED
};

void setup() {
pinMode (0, OUTPUT);
pinMode (1, OUTPUT);
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
pinMode (7, OUTPUT); // PORT D

pinMode (8, OUTPUT); // WR PIN (inverted)


for (byte k = 0; k < strlen_P(img); k++) {

digitalWrite(8, LOW); // inverted so this puts WR HIGH (to read)
delay(10);

myChar = pgm_read_byte_near(img + k);
PORTD = myChar;

digitalWrite(8, HIGH); // inverted so this puts WR LOW (to write)
delay(10);

}
}
void loop() {
}

Success finishing the board and recording Palladio distorted by the board :

 

 

 

Here is the setup :

I’m currently using two boards, but soon I’ll have the components to put everything on the board to the left. 

The techniques I’m using is the one developed in the previous post :

TO RECORD IN BURSTS: I can now save a short video : 695.45 kHz (This is the slowest I can go and still almost see an image) on the function gen AND’ed with the top 4 frequency divisions of the vertical sync. This makes for a burst of image recording every X number of frames.  I then amplify the output to make it visible on screen (and speed the clock up to 695.48 kHz). 
TO STOP THE IMAGE JUMPING: If the reset is connected to the inverse of the freq subdivision of the vertical sync signal AND’ed with the address 20, it will play the image in a loop and always place it in the same part of the screen ! 
EXPERIMENT : 1 bit recording 

Recording a single bit of an image appears to produce almost the same image quality ! This means that in theory I could record 8 videos at the same time and output video to 8 screens simoultaneously !

 

EXPERIMENT : Loading an image with Arduino
Loading the tiny image once was a drop of water in the ocean so I recorded the image again and again until I ran out of space. This is taking a long time with a few 10ms delays in my code. 

 

Here is the Arduino sending bits (captured after DAC) :

 

but so far nothing that comes out looking like an image on the other side…

I also can’t get my VGA to HDMI converter working…

Here’s an attempt at a grid of raster variations :

Here’s the final version of the board :

 

Memory Experiments

 

https://github.com/merlinmarrs/Video-Memory

This project started with an ambitious board combining ADC, DAC and SRAM. 

 

There were too many issues so I broke the board down into two parts: a memory board and a ADC/DAC board. This allowed me to isolate things and proceed in a step by step way.

I discovered that the memory needed a WR signal inbetween clock address refreshing, and for the second board that my op amp choice was inappropriate and needed to work around it (by using the DAC only as an R2R ladder and skipping the op-amp for the ADC input). 

 

During assembly I found that several 0 ohm jumpers were causing shorts. I also tore out the 8 pin header but applying too much force accidentally. Otherwise the switch system was very effective to test my understanding of the memory chip operation. It can essentially record a series of button manipulations for about 1.5 minutes.  

Here is my first successful “recording” of a sine wave through the ADC and into SRAM and play back from SRAM through the DAC :

BOARD ERRATA:

-need last bit of address counter (cuts memory in half !)

-more jumpers should be broken out for testing (like alternative op amp for input, clk for various chips, etc.)

-leds burn out when activated and output plugged into 5V at the same time…

-GND and 5V switched on the two boards 🙁

-Wrong op amp spec’d. The ADC1175 suggests the LMH6702MF and a choke between power supplies. 

-caps on all ICs

-the LEDs I set up on the microchip are plugged into ADC…

-Add enable header on microchip board

-power LED on the ADC board

-add a MSB and LSB next to LEDs on memory board **

I calculated how much I could store in the 4K of the SRAM I am currently using, and it would be a single line of a 600×800 screen at 40Mhz pixel frequency…

So what can I do with this ? I could record 4,000 pixels of a static image (i.e. lower the resolution of the image to 100×400 for instance) and then play it back. This would require me to control the sampling of the ADC with the CLK pin of the ADC1175 for every X pixels, somehow synchronized with the VGA in signal (use timing signals of an incoming VGA signal set), or to generate a custom VGA output signal with different timing using the VGAX library. 

Some important references : 

nootropicdesign.com/video-experimenter/build

gieskes.nl/visual-equipment/?file=gvs1

I am looking into what I could draw on screen with only 4K memory at a 20MHz clock.

EEPROM and SD cards are also interesting before reaching the holy grail of magnetic recording media of course…

I have the AT28C256F-15TU EEPROM chip which has 256K x 8 bits (enough to at least store an entire 600×800 static screen) and the ADV7125STZ50 8 bit triple HS video DAC. 

https://www.mouser.fr/datasheet/2/268/doc0006-1108095.pdf

https://www.mouser.fr/datasheet/2/609/ADV7125-1503638.pdf

I’d like to have a standalone arduino VGAX based board (https://github.com/smaffer/vgax) which can output 120×60 pixels and reads from internal SRAM and can record and playback. With 256K I could record a static image on screen at a higher resolution or a low resolution short video.

I have already made an SD card image saving board: 

Just realized what I’m trying to do is called a frame grabber and it’s a massive PCB :

https://en.wikipedia.org/wiki/Frame_grabber#:~:text=A%20frame%20grabber%20is%20an,or%20a%20digital%20video%20stream.&text=Historically%2C%20frame%20grabber%20expansion%20cards,to%20interface%20cameras%20to%20PCs.

 

*********************************************************************************

I have designed a similar memory board but using a 256K EEPROM chip in place of the  SRAM and with VGA connectors to begin testing images. (There do appear to be larger SRAMs, going up to 16MB. There are obviously large flash memories in SD format going into the GBs which may also be interesting to play with).

-Added out VGA to work with VGAX library (not sure if need a second microchip to handle just the memory stuff?)

-Added a 16MHz resonator

-With two 8 bit counters to have the full 13 bits to control this time.

-EEPROM will keep a recording after power down.

-can control buffers with microchip

Just learned that EEPROM is probably the slowest…

Just a thought but I could save control signals for the 0c74 instead of saving actual pixel information…

*************

First test (WORKING):

int switchState = 0;

pinMode(6, OUTPUT); // CLK LED (*)
pinMode(7, OUTPUT); // CLK

pinMode(10, OUTPUT); // WR/RD SIGNAL TO SRAM
pinMode(A3, INPUT); // WR/RD SWITCH (WR HIGH, READ LOW)

pinMode(8, OUTPUT); // WR LED
}

// the loop function runs over and over again forever
void loop() {

switchState = digitalRead(A3);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (switchState == LOW) {
// WR selected on switch so turn WR LED on and send a LOW to SRAM

digitalWrite(8, HIGH);
//
digitalWrite(10, HIGH);
digitalWrite(6, HIGH); // 
digitalWrite(7, HIGH); // 
delay(10);
digitalWrite(10, LOW);
digitalWrite(6, HIGH); // 
digitalWrite(7, HIGH); // 
delay(10); // 
digitalWrite(10, LOW);
digitalWrite(6, LOW); 
digitalWrite(7, LOW); 
delay(10); // 
digitalWrite(10, HIGH);
digitalWrite(6, LOW); // 
digitalWrite(7, LOW); // 
delay(10); // 

}
else {
// READ selected on switch so turn WR LED OFF on and send a HIGH to SRAM
digitalWrite(10, HIGH); // STAYS HIGH THE WHOLE TIME
digitalWrite(8, LOW);
//
digitalWrite(6, HIGH); // 
digitalWrite(7, HIGH); //
delay(20); // 
digitalWrite(6, LOW); // 
digitalWrite(7, LOW); // 
delay(20); //

}

}

This is what it produces:

Second test (WORKING): 

int switchState = 0;

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(6, OUTPUT); // CLK LED (*)
pinMode(7, OUTPUT); // CLK

pinMode(10, OUTPUT); // WR/RD SIGNAL TO SRAM
pinMode(A3, INPUT); // WR/RD SWITCH (WR HIGH, READ LOW)

pinMode(8, OUTPUT); // WR LED
}

// the loop function runs over and over again forever
void loop() {

switchState = digitalRead(A3);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (switchState == LOW) {
// WR selected on switch so turn WR LED on and send a LOW to SRAM

digitalWrite(8, HIGH);
//
digitalWrite(10, HIGH);
digitalWrite(6, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1);
digitalWrite(10, LOW);
digitalWrite(6, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
digitalWrite(10, LOW);
digitalWrite(6, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, LOW); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
digitalWrite(10, HIGH);
digitalWrite(6, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, LOW); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
// wait for a second
}
else {
// READ selected on switch so turn WR LED OFF on and send a HIGH to SRAM
digitalWrite(10, HIGH); // STAYS HIGH THE WHOLE TIME
digitalWrite(8, LOW);
//
digitalWrite(6, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, HIGH); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second
digitalWrite(6, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(7, LOW); // turn the LED on (HIGH is the voltage level)
delayMicroseconds(1); // wait for a second

}

}

And here are some shots of what three different speeds (10ms, 10microseconds, 1 microseconds) as delay in the Arduino code :

 

***********************************************************************

Third test (NOT WORKING):

I recorded a sine wave at 100KHz (with WR activated on the microchip board) with the ADC being clocked at 10KHz. I made sure I had the ADC selected with the right buffers and then sent this 8 bit sequence to the memory where I recorded it with a new Arduino code:

void setup()
{
DDRD = B11111111; // set PORTD (digital 7~0) to outputs
DDRB = B11111111; // set PORTB (digital 7~0) to outputs
}

void loop()
{
if((PINC & 0b00001000)==0)
{
PORTD = B11111111; // set PORTD pins (digital 7~0) high
PORTB = B00000000; // set PORTD pins (digital 7~0) low
PORTD = B00000000; // set PORTD pins (digital 7~0) low
PORTB = B11111111; // set PORTD pins (digital 7~0) high

}
else
{
PORTB = B00000100; // WR PULLED HIGH SO TURNED OFF
PORTD = B11111111; // set PORTD pins (digital 7~0) high
PORTD = B00000000; // set PORTD pins (digital 7~0) low
}
}

/*
CLOCK:
_____ _____
| ` | | |
___| |___| |____

WR:
_________ ____________
` | |
|___|

*/

I then switched to the DAC with the buffers and switched into READ mode on the microchip board.  Now the 8 bit sequence was being translated back into a sine wave. I took this sine wave and amplified it with an audio amp and sent it to the three color channels combined with an arduino running the VGAX pattern code without the colors plugged in and only H and V SYNC.

I got this on the screen :

Here is the tentacular and unoptimized setup :

To make this actually easy to use, I need to:

-have the microchip control the buffers and the ADC clocking based on the switch state.

-have the memory and adc on a single board.

-have a VGAX out setup integrated into the memory board.

-have an op amp on the ADC board to amplify the output signal !!

-have a dial change the speed of the playback / sampling of recording.

*******************************************

I added an external crystal and set the AVR dude Fuses to : Ext. Crystal Osc.8.0 – ___MHz 16K CK/14 CK + 65 ms. 

I added F_CPU 16000000UL ABOVE the #include. 

Forgot that if you don’t add 0b before a binary number nothing happens with the pins !

Here is the code that still isn’t working :

/*
* eeprom board v.2.c
*
* Created: 06/02/2022 09:19:50
* Author : Jonah
*/

#include <avr/io.h>

int main(void)
{

DDRC = 0b00000000; // PC3 is the switch for WR (0) or RD(1)

DDRD = 0b11111111; //PD5 is CLK and PD4 is !OE

DDRB = 0b11111111; //PB0 is the LED and PB2 is !WE

while (1)
{

/*
BYTE WRITE: A low pulse on the WE or CE input with CE or WE low (respectively) and OE high initiates a write
cycle. The address is latched on the falling edge of CE or WE, whichever occurs last. The data is latched by the first
rising edge of CE or WE. Once a byte write is started, it will automatically time itself to completion. Once a
programming operation is initiated and for the duration of tWC, a read operation will effectively be a polling operation.
*/

if((PINC & 0b00001000)==0) // WRITE MODE: (CE -> TIED LO); !WE -> TOGGLE ; !OE -> HI ; CLK -> TOGGLE
{
PORTD = 0b00010000; // !OE -> HI ; CLK -> LO
PORTB = 0b00000000; // !WE -> LO
PORTB = 0b00000001; // !WE -> LO (to make the pulse width at least 100ns)
PORTB = 0b00000101; // !WE -> HI
PORTD = 0b00110000; // !OE -> HI ; CLK -> HI (next address must come a max of 50 ns following !WE going HI?)

}

/*
READ: The AT28C256 is accessed like a Static RAM. When CE and OE are low and WE is high, the data stored at
the memory location determined by the address pins is asserted on the outputs.
The outputs are put in the highimpedance state when either CE or OE is high. This dual-line control offers designers flexibility in preventing bus
contention in their system.

*/

else // READ MODE : (CE -> TIED LO); !WE -> HI ; !OE -> (TOGGLE ? OR JUST LO?) ; CLK -> TOGGLE
{
PORTB = 0b00000101; // !WE -> HI
PORTD = 0b00100000; // !OE -> LO ; CLK -> HI
PORTD = 0b00000000; // !OE -> LO ; CLK -> LO
}
}
}

**********************************************************************************

One question I have is: does the EEPROM require OE to go on and off when reading unlike the SRAM I worked with in the previous board ?

Another question is, how long does the EEPROM need to write a byte ? It talks about “access times of 150ns”…?

Is it OK I have CE tied low the whole time ?

As a next step I will try doing all of this but very slowly to see if that works. 

*EDIT : tried slowing everything down and I’m still not able to load anything into the memory :(. I just get 5V and little pops of ground after writing ground into every cell of the memory. This is after changing !OE toggle and always ON also. 

I did get the VGAX code running though so at least that works. 

ERRATA:

-the labeling of WR and RD are confusing, when the switch is to the RD side it is in WR mode etc. 

-the VGA parts are COMPLETELY wrong. 

-I need to order 16MHz of this format (I took one from a dead Arduino board). 

-the text is too small and came off during cleaning.

 

TROUBLESHOOTING AT28C256 EEPROM:

-Need to wait a second before doing and writing or reading,

-Need to either wait the maximum time for the EEPROM to write (Write Cycle Time Max AT28C256 = 10ms) or poll 1/0 7 to wait until it matches what you sent it before starting another write cycle.

-The device may be locked (even though the devices should ship unlocked) :(. The unlock sequence is :

LOAD DATA AA
TO
ADDRESS 5555

LOAD DATA 55
TO
ADDRESS 2AAA

LOAD DATA 80
TO
ADDRESS 5555

LOAD DATA AA
TO
ADDRESS 5555

 

LOAD DATA 55
TO
ADDRESS 2AAA

LOAD DATA 20
TO
ADDRESS 5555

LOAD DATA XX
TO
ANY ADDRESS(4)

LOAD LAST BYTE
TO
LAST ADDRESS

 

************************

Here are some thoughts I have on the SRAM device :

Do I want addressed to loop or not ? (Add inverter if want to loop)

  >> Make it optional with a jumper, this expands the possibilities of experimenting.

Max sample rate I can get from SRAM ? 
>>Looks to be around 20MHz if the read time is 50ns ?
What happens if I slow a recorded signal down with a knob, what visual effects produced ?
>> I need a bunch of recorded stuff and a super fast clock or else I just output bands everyonce and a while.
Bigger SRAM same brand? need more counters?

  >> Check out this super fast 1Mx8bit SRAM

61-64WV10248EDBLL-276598.pdf (mouser.fr)

Two memories ? Feedback from one memory possible ?
Jumpers to either have vgax doing syncs or input vga.
Record at slow speed play back at high speed ? Keeps theme of time and computation…
How have vgax send clock and wr signal for memory circuit while doing vgax timing ? Or have separate clocks (high speed resonator) and sync somehow ? ( Or generate my own sync sign also in logic ?)
How actually use and function with two vgas ?
It would be cool to be able to record an image, or parts of a series of images, on an input vga signal and then play them back at different speeds and doubled with the original. This seems really challenging to do accurately but could be cool to stretch an image or sample every line from an animation.

Also would be cool to be able to output blocky animations based on memory. Could vgax output memory values? Then could compose.

Could the vgax do a kind of low fi screen capture ? This is a ripoff of gieske though…
Could this thing be a composition machine, where you slowly switch 8 pin dip switches and take a “photo” of each finished byte ? Then play back at higher speeds?
I started this board wanting to learn about memory. What have I learned ? Could have button to reset address counters, knob for clock speed, but what other Params?
Could take memory and output it as pattern by vgax ?
Do all first with Arduino analog read  ?? Why is this better than Arduino ? What advantage, what has it allowed me to learn ? Faster ? Physicalized memory space ?
**********
Retried this code modified slightly from this tutorial : https://scanlines.xyz/t/tutorials-for-generating-video-sync-signals-with-arduino/104

#define LINE_CYCLES 508
#define HSYNC_CYLCLES 60
#define VSYNC_LINES 2
#define FRAME_LINES 525
#define PIXEL_FREQ 1

volatile int linecount;

void setup(){
pinMode(7, OUTPUT); // VSync
pinMode(9, OUTPUT); // HSync
pinMode(6, OUTPUT); // Pixel frequency

//inverted fast pwm mode on timer 1
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

ICR1 = LINE_CYCLES; // Overflow at Cycles per line
OCR1A = HSYNC_CYLCLES; // Compare high after HSync cycles

//timer 0 in CTC mode
TCCR0A = _BV(COM0A0) | _BV(WGM01) ; // Toggle pin on each cycle, no CPU clock prescaling/
TCCR0B = _BV(CS00); // no clock prescaling
OCR0A = PIXEL_FREQ; // go super fast

TIMSK1 = _BV(TOIE1); // Enable timer overflow interrupt
}

ISR(TIMER1_OVF_vect)
{

if (linecount == 0) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 2) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 3) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == FRAME_LINES) linecount = 0;
linecount++;
}

void loop(){}

*******************

Works well. Also tried generating my own V and H sync with logic and a 4040 counter from this tutorial : https://hackaday.io/project/9782-nes-zapper-video-synth-theremin/log/32271-vga-sync-generation

It didn’t work for me. The reset of the 4040 didn’t want to be connected to anything but GND, otherwise the whole thing was inoperational. 

I also messed around again with floppy disk writing. I got the floppy disk motor turning, plugged the index into step, activated the drive select, and connected direction to either 5V or GND. I soldered a connector for the 5 wires froming from the recording magnets. I tried blasting them with a sine wave added to a 10KHz square wave but saw no sign of the signals when playing back the floppy. 

I have a new plan: Triple SRAM device for copying and pasting a loop of very blocky “video” :

 

*****************************************************************************************

Here’s what I learned :

version 1 :

I need to make a smd breakout board for chips or order DIP versions so that I can do tests first. This would save a lot of time designing and redesigning boards. The idea for a minimal integrated board was good though. Break more pins out.

version 2 :

BOARD A : I need to make a more stable way to solder pin headers to the card so they don’t rip off easily. I should use buffers to protect the LEDs. There are also way too many jumpers between the the counter and SRAM. 

BOARD B : The op amps don’t work. The DAC doesn’t work as I wired it. I forgot to connect the CLK of the DAC.  

It’s a mess to connect the two boards, make the right connections. The two boards need to be integrated. 

version 3 :

The EEPROM doesn’t work, is it locked ? I also used the wrong VGA pins. 

version 4 :

It’s a beautiful board but the DAC was VERY challenging to solder by hand. I think the level of complexity and ambition of the board was a little bit too high for this production method. I think I should head back to a board that is easy to assemble, easy to test and understand. 

version 5: 

The idea : using buffers I can have LEDs display what is in the memory while also outputing analog output. There are fewer jumpers than in earlier versions. I am planning to use the inverter to control the SRAM WR which appears to be possible based on the datasheet. Simplified DAC with R2 ladder, I can control A12 with a switch and have an A11 LED now. I got rid of the VGA functionality – this makes things simpler. I chose switches over shunts to make connections.

I want to make 3 of these boards, ABC, so that they can each record in two 4K memories, and then do cool logic transformations and save the results too. Connecting the ADC to the SRAM inputs requires 8 jumpers, and I’ve done away with 8 pin dip switches. To manually set data you connect the jumpers to the spare + and – headers. 

I would like the decisions to be guided by how I could practically use this device to “record” 8 bits of data / an analog signal for a given period of time (based on the clock speed) and then play it back (while modifying the clock speed manually, and overwriting portions of the memory, possibly from another pair of memory boards) to display on a screen (with another board handling the VGA signals and optionally sharing its clock with this board to keep things in sync). I want to move to something that produces output ASAP, and away from endlessly redesigning these boards looking for something perfect. (If this works I want to make 3, then a specialized VGA board too).

I’ve added reverse polarity protection, a STEP button, which is hardware debounced, to manually advance one address at a time. I kept the op-amp modular so that it could be used to amplify analog in or out. I switched out the edge accessible thumb pots for normal pots, so this thing is no longer really stackable.

Not sure exactly how they stack (but many things accessible on the edges) though and not sure if I should have a battery included or not so that it remembers what it recorded…

Version 5 UPDATE :

Thoughts on possible  version 6 additions :

Backup battery to record option ?

8pin dip switch with header somewhere on board?
Question I have to resolve with current version :
What can I record (in analog and in digital) and for how long ?
What does it look like on the screen with and without a generated pixel clock to do the sync?
Going at pixel frequency speed I can draw different repeating textures on the screen when I record very slowly and then speed it up :

Patterns are repeating, it’s like a texture. Sending a non-repeating signal, like the arbitrary function signal which leaves a non-repeating pattern on screen, seems like a cool thing to try. Another option is to have a single block of memory but to jump around in how you address it somehow ?
How fast and how slow can it go ?
With a 10K resistor and a 0.1uF for the CD4046 I have a max sampling speed of 1Khz that is barely enough to represent a 100 Hz sine wave.
Apparently this max is called the Nyquist frequency :

Nyquist Frequency=Fmax = SampleRate/2

The SRAM module IS61C64AL can run up to 20MHz according to the datasheet (https://www.issi.com/WW/pdf/61C64AL.pdf)

When I feed it the 3MHz pixel frequency from the modified VGAX it can record a 1.5MHz sine wave and play it back ! The problem when it is going slow is that it just outputs bands every now and then. It could act as a memory of a control signals which would change parameters in a circuit which generates more interesting output. (It could even control an analog computer like this https://the-analog-thing.org/ ).
The other option would be to have a super fast clock that is connected to the V and H sync, one that I can divide and use to control recording of a large SRAM memory.
Would second mem board be cool ?
Not unless I get a bigger SRAM I think and daisy chain a series of 8 bit counters :
https://www.mouser.fr/datasheet/2/198/62-65WV10248EALL-BLL-462620.pdf
VERSION 5 UPDATE :

Here are the issues :
-I added a reset for the counters to go back to address 0. It takes a while to kick in though – I think because it resets the counter but not the 8 bit storage register ?
-I added an LED to show when ADD21 is activated.
-the 74F541 does not like 5V. I replaced it with an 74HCT254 and pulled the DIR pin HIGH.
-the ADC1175 operates at 4.5-5.5V ! (I will test it’s max speed – supposedly 20MHz by powering it with 5V)
-One pin connection missing on 8 pin dip switch
-The phase shifter sucks and the amp doesn’t currently work.
-CS should be held down and not toggled with WE.
-RCO for cascading counters was not working at higher frequencies – I switched to sending the last Qout of each counter to the CLK in. 
-I don’t have a way of taking 5V analog signals and stepping them down to 3.3V.
-The memory should default to floating (instead of ground?) so that I can re-record over previous stuff. (Currently when I re-record, if a pin is not set it defaults to being black and just erasing everything).
-need a 3.3V to 5V booster if you want to interface with another 5V memory. It would be nice to have an in-line 8 plug so I don’t need to plug in each wire one by one…
-I can’t currently take VGA in at 400×800 from a computer (amplified) and saved it into the memory (it’s pixel clock is at 40MHz, I set the function generator to 4MHz). But I can record an image imperfectly from the VGAX color out at around 1.3038210 MHz.
-I need to amplify at the input and the output (and ideally be able to offset them both and up and down – especially to hit the middly of the CMOS threshold between low and hi if I want to record in image in b&w with a single bit). The next version of the board would have two amps.
-When I play back a recording, each time the memory restarts at zero, the frame of the video moves. (To solve this I need the freq divider, AND chip and inverter).
-Pin 11 of the ADC should be connected to 3.3V while pin 13 should be connected to 5V.
Possible improvements:
-a 5V power in with 3.3V LDO so I can power things with both ?
-if I want to upload something to memory, and then change to outputing, I have to disconnect all the wires that were connected to it previously. I should have a 74HCT254 Bus transciever that can change directions to disconnect a set of 8 wires from the memory. ALTERNATE OPTION : Just keep everything plugged in and turn off ADC?
-Maybe an LED that tells me I’m recording (easy not to notice that it’s not in recording mode and then connect it to outputs that are pulling it up and down). 
-Would be cool to be able to select which chunk of memory I’m replaying over with two knobs that control the start point and end point. (This could be two comparators connected to two pots ?)
Developements:
I can load values into the memory from Arduino’s PRGMEM like so:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* TO LOAD DATA INTO THE MEMORY */

#include <avr/pgmspace.h>

byte myByte;

#define IMG_PIRATE_BWIDTH 30
#define IMG_PIRATE_HEIGHT 60
//data size=900 bytes
const byte img_pirate_data[IMG_PIRATE_HEIGHT*IMG_PIRATE_BWIDTH] PROGMEM={
0, 7,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 63,252, 6, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0, 0, 0, 0, 0,
2,255,112, 96,129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15,222, 2, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
255,240, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
252, 65,144, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
248, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 0, 0, 0, 0, 0, 0,
65,132, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,
0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
36,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0,
32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,130,168,160, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,138, 42, 32, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34,136, 32,130, 0, 0, 32, 0, 0, 0, 1, 69, 64, 80, 0, 20, 5, 4, 0,
32, 0, 0, 0, 0, 0, 0, 8,170,160, 0, 0,170,170, 40, 42,170,136, 0, 0, 0, 0, 64, 17, 4, 68, 64, 16, 68, 0,
0, 0, 0, 0, 0, 0, 0,162, 10, 2,170,170,170,170,168, 32, 0, 34, 0, 0, 0, 0, 65, 65, 4, 16, 84, 16, 68, 0,
64, 0, 0, 0, 0, 0, 10,130,171,239,255,238,170,170,160,162,170,162, 0, 0, 0, 0, 68, 1, 4, 16, 65, 16, 64, 0,
36, 0, 0, 0, 0, 0, 8, 42,187,250,170,170,187,238,250, 0, 0, 34, 0, 0, 0, 0, 69, 80, 80, 68, 20, 5, 4, 0,
0, 0, 0, 0, 0, 0, 34,170,255,234,170,170,171,187,178, 60, 0,170,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152, 0, 0, 0, 0, 0, 0,171,254,170, 0, 2,186,255,248, 61, 3, 2, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1,196, 0, 0, 0, 0, 10,187,254,168,112, 4,171,191,248, 54, 0, 40,136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8,198, 96, 0, 0, 42,191,250,163,240, 14,174,255,254,136,170,138, 34,128, 1,128, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,139,191,250,168, 53, 26,171,255,252,138, 34,186,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 42,251,250,170,170,170,174,191,254, 34,187,174,232,128, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2,170,174,255,186,170,170,187,255,255, 34,234,251,170,128, 0,128, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0,138,187,187,171,170,238,187,191,255,138,175,255,238, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 10,239,255,186,186,170,238,239,255,224,235,255,250, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 46,175,255,255,238,186,190,255,255,248,171,255,250,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,170,191,255,255,250,171,187,239,255,254, 42,255,238, 32, 0,144, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 42,238,255,255,251,170,174,187,255,254,174,190,234,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1,128, 0, 0,174,187,255,255,254,235,171,255,255,254, 10,171,170,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 32, 0, 0, 0,138,174,255,255,255,186,163,255,255,255,162,186,186,128, 0, 4, 36, 0, 0, 0, 0, 0, 0, 0,
0, 4, 0, 0, 0, 0, 43,187,239,255,254,170,234,170,174,234, 34, 42,168, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 10,174,186,255,251,171,168,128, 10,128, 2, 34,226, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0,
0, 0, 64, 0, 0, 0, 2,171,239,187,254,234,170, 40, 0, 0, 0, 40, 32, 0, 0, 2,170,168, 0, 0, 0, 0, 0, 0,
0, 0, 40, 0, 8, 0, 0, 42,190,239,190,186,128, 0, 0, 0, 0, 0,160, 0, 0, 64,170,170,160, 0, 0, 0, 0, 0,
0, 2,160, 0, 60, 0, 0, 42,171,190,250,168, 0, 0, 10,170,168, 0, 0, 0, 0,128, 16, 10,168, 0, 0, 0, 0, 0,
0, 42,128, 2,240, 0, 0,130,234,186,170,160, 0,170,170,170,174,128, 0, 0, 0, 6, 0,170,170,128, 0, 0, 0, 0,
0,170,128, 47, 0, 0, 0, 10, 42,170,170,128, 42,170,175,255,250, 32, 0, 0, 1, 0, 42,170,170,168, 0, 0, 0, 0,
10,170, 64, 40, 48, 0, 0, 0, 40,162,170, 0,171,255,255,255,234,136, 0, 0, 2, 0, 2,170,170,170, 0, 0, 0, 0,
170,170, 0,160,176, 0, 0, 0, 0,130,168, 2,191,186,175,250,170, 32, 0, 0, 1, 56, 0,170,170,170, 0, 0, 0, 0,
170,170,130,130, 64, 0, 0, 0, 2, 8,168, 10,239,255,234,170,170,136, 0, 0, 16, 60,128,170,170,170, 0, 0, 0, 0,
170,170,128,138, 0, 60, 0, 0, 0, 8, 32, 2,255,255,255,234,186,128, 0, 0, 0, 7,232, 42,170,170,128, 0, 0, 0,
170,170,160,168, 0,252, 0, 0, 0, 0, 0, 10,175,255,255,251,170,128, 0, 0, 0, 0, 26, 42,170,170,128, 0, 0, 0,
170,170,168, 8, 0,240, 32, 0, 0, 0, 0, 8,190,187,235,238,168, 32, 0, 0, 0, 0, 4,170,170,170,160, 0, 0, 0,
170,170,160,170, 0,240,192, 0, 0, 0, 0, 0,170,254,238,170,186, 0, 0, 0, 0, 0, 72, 42,170,170,168, 0, 0, 0,
170,168, 0,170,128, 2, 64, 0, 0, 0, 0, 0, 2,171,170, 58,160, 0, 0, 0, 0, 0, 2, 10,170,170,170,128, 0, 0,
170,170, 42,170,168, 3, 0, 0, 0, 0, 0, 0, 2, 10, 42, 8, 0, 0, 0, 0, 0, 0, 1, 42,170,170,170,168,128, 0,
170,170,170,170,169, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 18, 42,170,170,170,170,168, 0,
170,170,170,170,168, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,128, 0, 42,170,170,170,170,170, 0,
170,170,170,168, 36, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,188, 96, 15,170,170,170,170,170,170, 0,
170,170,170,170, 0,130, 14, 96, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, 63,234,170,170,170,170,170,128,
170,170,170,170,170,170,143,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,249,240, 63,234,170,170,170,170,170,128,
170,170,170,170,170,170,144, 63,240, 0, 0, 0, 0, 65, 0, 0, 0, 15,192, 0, 63,144, 63,170,170,170,170,170,170,160,
170,170,170,170,170,170,175,239,240, 0, 1, 0, 0, 2, 24, 0, 0, 15,252, 0, 7,228, 15,218,170,170,170,170,170,168,
170,170,170,170,170,170,168,255,240, 48, 64, 0, 13,129, 1, 0, 0, 3,255, 0, 0,114, 15,250,170,170,170,170,170,170,
170,170,170,170,170,170,170, 62,192,188, 0, 0, 63,126,192, 36, 0, 2,127,208, 0,185,191,250,170,170,170,170,170,170,
};

void setup() {

Serial.begin(9600);

pinMode(7, OUTPUT); // I/O 8
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);
pinMode(4, OUTPUT);
pinMode(3, OUTPUT);
pinMode(2, OUTPUT);
pinMode(1, OUTPUT);
pinMode(0, OUTPUT); // I/O 0

pinMode(8, OUTPUT); // CLK

for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}
for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + 200+ k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}
for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + 200+ k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}
for (byte k = 0; k < 200; k++) {
myByte = pgm_read_byte_near(img_pirate_data + 200+ k);
Serial.print(myByte);
digitalWrite(8, LOW); //CLK LOW
delay(1);
PORTD = myByte;
digitalWrite(8, HIGH); //CLK HIGH
delay(1);
}

Serial.print(“FINISHED”);
}

void loop() {

}

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

I have a different Arduino to trigger the memory on each pixel and generate the sync signals :
/* TO TRIGGER MEMORY CLOCK EACH PIXEL AND GEN VGA SYNCS */

#define LINE_CYCLES 508
#define HSYNC_CYLCLES 60
#define VSYNC_LINES 2
#define FRAME_LINES 525
#define PIXEL_FREQ 1

volatile int linecount;

void setup(){
pinMode(7, OUTPUT); // VSync
pinMode(9, OUTPUT); // HSync
pinMode(6, OUTPUT); // Pixel frequency

//inverted fast pwm mode on timer 1
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

ICR1 = LINE_CYCLES; // Overflow at Cycles per line
OCR1A = HSYNC_CYLCLES; // Compare high after HSync cycles

//timer 0 in CTC mode
TCCR0A = _BV(COM0A0) | _BV(WGM01) ; // Toggle pin on each cycle, no CPU clock prescaling/
TCCR0B = _BV(CS00); // no clock prescaling
OCR0A=PIXEL_FREQ;

TIMSK1 = _BV(TOIE1); // Enable timer overflow interrupt
}

ISR(TIMER1_OVF_vect)
{

if (linecount == 0) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 2) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == 3) PORTD = PORTD ^ 0x80; //Toggle the most significant bit of port D.;
else if (linecount == FRAME_LINES) linecount = 0;
linecount++;
}

void loop(){

}

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
UPDATE:
I finally have a screen I can use to subtract the memory contents with :

#include <VGAX.h>

VGAX vga;

void setup()
{
vga.begin();
vga.clear(11);
}
void loop(){for (int y=0; y!=VGAX_HEIGHT; y++) {
for (int x=0; x!=VGAX_BWIDTH; x++) {
vga.putpixel(x, y, 3);
}}}

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

I now can use this with an AND chip and my own function gen frequency and output from the SRAM !

And here are some of the images I’m getting (using an AND also for the clock coming from the signal gen) :

And here I am trying to record VGA…
…from VGAX (120×60):

 

…and from a computer VGA at 800×600 passing along the sync signals:

Here was what was onscreen :

Test card - Wikipedia

I can reproduce this reliably with :
-op amp taking memory and amplifying it
-a pixel clock at 1.007MHz (pixel clock for 640×480 of 25.175 MHz divided by 25)
But it kinda turns on and off and also jumps around on the screen for some reason.
I also found out I could use the vertical sync along with a counter (taking as input a 4MHz fucntion generated square wave) and a bunch of AND gates to essentially only record only every X frame and store it in memory. This meant I can save way more frames. Getting the right spacing for the frames will be key to be able to store a short video. 
UPDATE 1:
I can now save a short video : 695.45 kHz (This is the slowest I can go and still almost see an image) on the function gen AND’ed with the top 4 frequency divisions of the vertical sync. This makes for a burst of image recording every X number of frames.  I then amplify the output to make it visible on screen (and speed the clock up to 695.48 kHz). One problem is that it looks like everything is in fast forward and it’s barely possible to interpret the images. The other issue is once the video starts again from memory its frame moves with regards to the screen. 
UPDATE 2:
If the reset is connected to the inverse of the freq subdivision of the vertical sync signal AND’ed with the address 20, it will play the image in a loop and always place it in the same part of the screen ! 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TESTING MAX ADC SPEED:
I’m not sure what to make of this as the signal was super noisy but, I can “follow” a sine that is at 50Hz sampling it at 5MHz fine. I’m not sure what conclusions to draw from this…

VGA controller board :

-Attiny(?) 
-several clock speeds to chose from
-knob to select diff screen resolutions
-PLL to sync to input VGA? Use an XOR to see delay with signal and then get closer to it ?
-easy setup to pass input VGA syncs to an output VGA
-filters to knock out certain frequencies to tune into what I want. 

 

ANALOG BOARD:

Based on the Analog Thing functionality (summing, multiplying, comparing, integrating, differentiating, etc.) along with counters to divide the screen by powers of two !

 

UPDATE:

Working now on a next version of the 16MB board. The idea is to fix the issues in the 16MB board, add more functionality, and also to move towards a finished board that is more plug-and-play with regards to recording VGA signals and less of a prepared instrument for testing. It’s a test to see if I could make something that behaves like a product.

One question is if it requires an analog function generator or not, and to what degree the machine is mono-functional or not. (Though I think if it could record video reliably and display to a screen that would already be not bad.)

Fixes :

  • A21 LED added
  • Top and bottom bias of ADC now controllable with pots
  • op amps on input and output both with variable gain and bias
  • fixed 5V and 3.3V power (ADC and op amps need 5V) with onboard LDO.
  • got rid of phase shifter and 8 pin dip switch
  • CS no longer tied to WR on SRAM.
  • various enables broken out so they can be turned on an off with external control 64KBSRAM
  • counters daisy chained with last address going to clock input of the following counter (no longer using RCO)
  • Replaced 74*541 with 74*245 (so it would have big footprint to let wires pass under but work with 3.3V)
  •  Added VGA in and out connectors and made pass thru mode for input.
  • Added f divider, AND, and NOT gates.

This board should allow me to test the idea of having a control board chroreograph a sequence of memory operations, and allow me to begin testing the analog board with a stable (not breadborded) video recorder. 

 

Sunflower Array

 

The github for this project :

https://github.com/merlinmarrs/tournesol

I’ve made the PCB for with the 74AC240 based on this design from http://www.smfr.org/robots/robot_images/dualsolarhead_schematic.png :

Hoping that it works better than the 540 version with the solar midpoint.

IT DOES! It is far more responsive and efficient and works with the solar panel! It has a funny quirk where it will first turn the wrong way then correct itself in one direction though…Next i’ll make it on a super small extra compact board and try the other circuit option:

It’s much more compact that the previous version. The photodiodes could be removed to make it even smaller. It took me around 25 minutes to assemble at a comfotable speed. By far the least efficient element of the assembly is the braided wire which is causing mini shorts :

There is already some interesting interplay with the two machines side by side…

3D model of fancy motor version:

Here’s a version with a tiny gear motor. The motor appears to lock up at low currents however so it doesn’t work super well. It’s also very difficult to attach the motor axle to the bottom platform. 

With the metal gearmotor it works much better:

And this version with the panels lower down:

Here is a tall version:

Here’s a compact design with a “flipper” arm:

The idea of pulling the solar panels from the board, exposing the electronics and creating the tilt naturally.

The little metal cap is actually a nice part of the look of the machine:

I have made the board thinner so that it fits perfectly over the gear motor:

Here’s a shot of it looking pretty:

Llama edition (it’s a heat sink). This photo makes me think I could have fun with shadows like in the 1970 Il Conformista film:

I see a monocled mustachioed Monopoly man here somehow:

This idea distributes the things to look at around the machine (one side has solar panels and the gear motor, the other has electronics and the underside gold lettering on the solar panels). When the machine is facing the sun we get to see the electronics. I guess the electronics is also sheltered from the heat of the sun a bit?:

Here are some feet ideas for the resin printer using small set screws and (in the right model) Pogo pins:

Here are two versions of the tripod design. One has the electronics as a backpack and hides it from the sun, the robot has two faces. The other has the “face” of the robot face the sun, in one photograph the whole robot is visible.

Version 1:

Version 2:

****

Side to side comparisons:

 Another idea for pogo pin feet using the crowned tips:

***

I made the barebones circuit in extra slim also:

debugging the previous version, it appears that the solar panels are indeed producing the expected voltage and current (2 x 1.67V, 18.4 mA), the voltage trigger and mosfet are working, the capacitor is charging, and the voltage to the motors is spiking. However the motors aren’t so much turning as twitching. The motors appear to be identical to others that are working however. Changing the capacitor from .22F to .15F changed nothing. 

EDIT:

I had another stab at this:

I noticed that the charging and triggering part of the circuit appeared to be working but that the motor was not firing. I assumed then that there was a soldering problem on the 74AC240 pins somewhere. I tested a copy of the same boards from the same batch to see if there were any problems with the etching itself, they all seemed good with no shorts and clean traces. I tested a blank 74AC240 as well and found that the only pins that were internally connected were 9 (Y1) and 10 (GND) – though I’m not sure why this is the case. I took a voltmeter to measure if there were any shorts between the pins on the IC and found that everything was mostly normal. Looking under the microscope it occured to me that the problem might be that the pins of the IC aren’t fully touching the pads below as they appeared to have been soldered quickly. In order to assume myself that everything was indeed well connected I reheated each of the pin connections and retested that I didn’t introduce any shorts. I then switched out the larger motor for a more efficient smaller DC motor. Testing with artificial light I now have normally functionality!

The second malfunctioning solar head has a different issue: It charges up fine from having no power and spins the motor no problem. But after a few times it stops triggering at hovers around 3.6V…I resoldered the connections and had the same issue. The voltage trigger appears to be triggering despite the voltage staying high. In the end I switched the bigger metal gearmotor for a small vibe motor and it worked just fine. I think I can conclude from this that the circuit I used is not suitable for the metal gear motors but works fine with smaller ones.

I am now looking into making this circuit even smaller using TSSOP-20 packages of the 74AC240 and maybe 0603 smd components too. I plan to make this double sided and to have the boards made at PCB way after testing a prototype circuit in the lab.

 

The circuit works fine after I had to resolder some of the IC pins to the pads (they seem to hover just above sometimes despite the soldering) and fixing a short between the two sides of the MOSFET by lifting up the positive side of the SMD cap up.

 

Testing with a single 3.4V panel and…it turns! I’m going to try to add the light detection now.

And this is how it could be integrated into the 2DOF design: 

This is a second option which would involve probably halving the above circuit and making it double sided. 

 

Another idea is to see how far this minimalism and miniturization can go, for instance with a single solar panel capable of charging up the cap to 3.3V ish. It could be 1DOF or 2DOF. Testing with the power supply with 4,46V @ 5,9mA it works no problem with the small gear motor. We’ll see if that’s the case with the actual solar cell soon.

Monocrystalline Solar Cell 24.5mW (4,46V Current – Short Circuit (Isc) 5,9mA)

https://www.digikey.fr/product-detail/en/anysolar-ltd/KXOB25-01X8F-TR/KXOB25-01X8F-DKR-ND/10127250

KXOB25-01X8F-TR ANYSOLAR Ltd | KXOB25-01X8F-DKR-ND DigiKey Electronics

Monocrystalline Solar Cell 26.3mW 5.53V:

https://www.digikey.fr/product-detail/en/anysolar-ltd/KXOB25-02X8F-TR/KXOB25-02X8FDKR-ND/9990483

KXOB25-02X8F-TR ANYSOLAR Ltd | KXOB25-02X8FDKR-ND DigiKey Electronics

Here is what it could look like 1DOF:

…and 2DOF:

If the solar panels are a bit offset from the boards then the light sensors could be directly on the board and not need to be offset themselves from the board. 

****

I actually have one of these lying around to test the one panel idea (3,4V
@ 4,4mA): 

https://www.digikey.fr/product-detail/fr/ixys/KXOB22-01X8/KXOB22-01X8-ND/2754274

Here it is working! (remember that the “GND” side of the photo bridge actually connects to the ENABLE of the 74HC240)

some other panel configurations:

I could have the light sensors on either end. 

A little higher up…

Satellite inspired:

Here’s a quick 3D print:

Not even sure if adding another DOF will have a big effect, over the course of a day how much will it actually tilt up or down?…

Dual Solar Tracking Part III

Another idea is to start with the actual solution (two small servos) and make it look better. It’s sturdy and already balanced. It just needs a hinge and a tilting arm:

With a makeshift hinge and tilt arm:

This would only require an Arduino mini pro and some super caps charged by a solar panel through a diode.

Some other more simple options:

For a miniature 2DOF.

A mini 1 DOF.

  The 2 metal gear motor design I was working with early on.

*****

Here is a super simple two servo motor controller that recharges supercaps through a diode:

This works with the code below as a test:

#include <Servo.h>

Servo myservo1; // create servo object to control a servo

Servo myservo2; // create servo object to control a servo

int pos = 0; // variable to store the servo position
int threshold = 100;

void setup()
{
myservo1.attach(5); // attaches the servo on pin 9 to the servo object
myservo2.attach(6); // attaches the servo on pin 9 to the servo object
}

void loop()
{

if (analogRead(A2)-analogRead(A3)>threshold)
{
myservo1.write(90);
delay(15);
}

if (analogRead(A3)-analogRead(A2)>threshold)
{
myservo1.write(-90);
delay(15);
}

if (analogRead(A4)-analogRead(A5)>threshold)
{
myservo2.write(90);
}

if (analogRead(A5)-analogRead(A4)>threshold)
{
myservo2.write(-90);
}
}

This is the monster in all its tentacularity:

****

Testing the barebones circuit with the solarbotics white DC gearmotors and the SMD solar engine. It works with only two mini solar cells and the SMD cap as long as the sun is medium strong!

 

This is exciting as a result (but I just needed the change the motor wire polarity):

Here’s what the circuit looks like:

This suddenly stopped working and I did the following things:

Checked to see if the cap was charging, if the voltage monitor was triggering (and I manually triggered the MOSFET to see if the motor fired), the voltage at the midpoint between the two photodiodes, and if there were any shorts.

In the end I replaced the zener with a normal SMD diode which I found, replaced the photodiodes with green LEDs because one lead was broken on the photodiode, and then discovered the motor was broken (or at least the blue wire was disconnected on the inside)! It gave me a chance to look inside the tiny gear boxes of the motors though: 

Here is the, once again, working prototype:

 

I would like to be able to tune the midpoint between the LEDs. I would also like smd light sensors. 

Phototransistor Output Voltage Circuit connects the phototransistor and 2 k-ohm resistor in series

Some options for solar panel and motor assemblies:

Here’s with SMD LEDs soldered on:

Not sure why but the thing is only turning clockwise…

I tried the following things:

  1. A 10K trimpot (with each photodiode into each side of the resistor and the variable pin going to the logic chip). The trim pot at either extreme does indeed make the circuit turn in the opposite direction. However, in the middle it stops either side from firing.
  2. Replacing the photodiodes with Silicon PIN Photodiode BP34s, green LEDs 5mm, Green SMD LEDS, and LDRs.
  3. changing the ground of the photodiode pair to the ground of the capacitor instead of the ground connected to the floating connected to the MOSfet.

Just found this image here (http://solarbotics.net/library/circuits/bot_popper_240.html) which seems to imply I could use phototransistors also:

Looking at other Smart Head circuits, it looks like the + side of the photodiode pair is connected directly to the Vcc but that the negative side is connected to the “local” ground, not the negative of the capacitor. However, there are also counter examples…

I tried just setting up the dual photodiode circuit on a breadboard. Two photodiodes , two LDRs etc. They each move from a midway value up or down depending on which device is in the dark. However, they don’t always have 1/2V as a midpoint, which appears to be the important threshold point for the oscillator. **EDIT** I think what they meant was half of VCC not 0.5V. I could try to find the exact threshold voltage that is the balance point with the power supply?

2.25V for my desktop breadboard version of the circuit while supplying 4V for the solar panel. 2.85V was the threshold with solar panels at 5V. It also has a dead zone where neither motor will fire if it is perfectly in the middle. 

For the soldered version the threshold is around 1.3-1.4V when being fed 4V as solar panel. 

At 3.5V solar panel supply, I have a lower threshold bound of 1.25V and a higher bound of 1.4V. In the deadzone neither direction turns. 

At 3V funny things happen. It will only turn one direction unless I suddenly make the input 0V. This might explain why my circuit is behaving strangely! I am using a 2.92V voltage supervisor so I don’t think my current circuit is ever going to work. 

I should replace it with a higher voltage threshold like this one perhaps: https://www.mouser.fr/ProductDetail/968-ISL88001IH46ZT7A 

In the meantime I can use a voltage divider like I did for the 1381. 

Here’s the scope output attached to one lead of the motor. The fat, fuzzy part is when the motor is not turning and the threshold is reached. Either side it sends between 1.5-2V to the motor turning one way or the other.

Setting up my own little trim pot between the LDRs I was able to tune them to the correct voltage threshold and everything works well on a breadboard at least.

Here is the 74AC240 datasheet: 

Checked out the 74AC240 datasheet, for 3.5V the threshold should be between 0.9V-2.1V.

****

Version 2 of the board has trimpots for the voltage trigger and the light sensors (which are now SMD and on either side of the board):

Here are the parts laid out with the new board:

Post-soldering. The size of the board versus two small solar cells:

I had to put electric tape under the trim pots because contacts were exposed underneath…  The full assembly:

****

Found this online here (http://www.smfr.org/robots/robot_images/dualsolarhead_schematic.png): 

It uses the solar panels as the light sensors! It also lays things out in an easy to understand way (the midpoint is the boundary between what the inverter sees as HIGH or LOW. Once the solar engine has enough power this decision of HIGH vs. LOW then powers the motor through six remaining gates – presumably to increase the current as each pin seems to be limited to 75mA according to the datasheet above?).

***

Testing V.2:

I can get 3.5+ volts (4V outside in full sunlight even) with the current setup of two solar cells + little cap!

BUT…When I short the voltage supervisor 5K trim pot the motor fires, but even in its least resistance position the supervisor is not triggering…It is also only doing mini movements, not full shots. I removed the trim pot and now it behaves normally. I don’t understand why the trim pot doesn’t work when it was flawless with the benchtop power supply…

With a 1M trimpot the variable voltage trigger does work just as expected, however! I moved it up to 3.5V ish.

The 5K trim pot for fine tuning the light sensors also does not appear to work. Also doesn’t work with a 1M and two green LEDs…

I tried using the two solar panels as sensors as suggested in the found circuit and it appears to work, there remains the same problem of how to tune the voltage level however if my trim pot solution doesn’t work. 

***

I think I need to order 74AC240s (I think the 74LS540s I am using might be slightly different in terms of their HIGH/LOW thresholds) or voltage triggers for 3.5V+. This is a nicely tuned circuit that seems hard to mess with.

Just a reminder of how much the complexity has been reduced in this project!:

***

I have realized I need to understand the circuit I am working with better in order to tinker with it. 

First thing, the 74LS540 that I am using has a minimum voltage of 4.5V! It also can only supply 45mA max as an ouput if I understand correctly. However, I also have a 74F244D octal buffer which works as low as 2V. However it is Bipolar and not CMOS technology like the 74AC240 AND more importantly, it has non-inverting outputs. Clearly getting the right logic chip and family is an important element and not a detail for this circuit…

So, the LDR “photo bridge”. After testing 10 we had lying around I arrived at these average values:

 

Here’s some R Thevenin calculations (Thanks to Learning the Art of Electronics!) to figure out what size pot I can afford to pull up or push down the midpoint from the LDR divider:

 

And here’s the current logic circuit in a more understandable format:

****

Did some tests, looks like I need to bring the midpoint DOWN in my circuit:

Yellow is the cap voltage (3.42V) and green in the midpoint (2V) with equal light on both phototransistors. 

This scope image shows first both photodiodes in light, then the left (connected to GND) in darkness, and finally the right (connected to VCC) in darkness:

Without even needing to take any measurements it’s evident that the midpoint is too high. This causes the motors to always turn the same direction when the light intensity is equal between the two phototransistors. I flipped the photo transistors and observed the same effect so I think it’s the circuit not the difference between the phototransistors.  

This scope image shows me adjusting the phototransistor trim pot. (Fully attenuating on the left, halfway in the middle and then fully open on the right). 

And here’s testing with the middle threshold covering and uncovering each phototransistor:

This shows that the 10K trimpot effectively drops the entire midpoint! I can effectively dail in the midpoint to exactly half of VCC now (3.42 Vcap, 1.71V threshold)!:

Now the machine is not turning in only one direction! But it also might need some resistors for when the two photodiodes are both seeing bring light. I also need to replace the LS540 with an AC240 because I am currently operating outside the maximum minimum voltage of the IC. It would also be nice to use the solar panel as a sensor and thereby reduce the part count (I could still tune the midpoint in the same way once I determine which way the imbalance is – it would also solve the shorting problem in high light). 

I varied the pot and everything is working as expected. I also added heat shrink to the phototransistors. Here is a video:

I tried some 2DOF designs but I think this needs to stay MINIMAL and the force of the project, if it comes, will come from the array more than individual complexity. Plus they already seem imbalanced and more likely to malfunction…

Some tests with the solar panel voltage divider:

Here’s what it looks like when I change the solar panel midpoint with the 10K trimpot:

Here is the solar panel midpoint trim pot all the way to one side:

Here is the solar panel midpoint trim pot all the way to the other side (not sure why it goes all the way to the ground here only):

Here is me putting one panel in the shade, then the other. The difference is not massive.

The problem is that now I fall into a large deadzone where no movement happens in the middle. I’m trying to find the right combination of voltage trigger trim level and solar midpoint level but it’s not easy without sunshine…

****

Here’s the cost per unit of this design:

74AC240: 0,462 €

0.2F cap: 1,21 €

solar cell: 3.56 € (1.78 € x 2)

micro gear motor: 4.25€

voltage trigger: 0,356 €

diode + 0.47uF cap: 0,1€

PCB: ?

Total: 9.938€ + PCB cost

****

I have now a 1M trimpot on the solar midpoint and have added a 1M between the midpoint and VCC to try to balance things out.

I think 3×3 is better than 4×4 ? 5×5 would be out of control.

****

Working towards simplifying the dual servo sun seeker. Here is a post for controlling servos without a microcontroller:

https://www.pololu.com/blog/18/simple-hardware-approach-to-controlling-a-servo

Could use LDR pair to replace pots inside the servos, based on ideas from Hackaday post shared with me by Paolo Salvagione:

Light Tracking Robot Relies on LDRs

 

***

Went back to the super simple business card sun shaker and added some feet. I also tested the new 0.2F caps and they work with outdoor light but might be too tough to charge with indoor light (unless it’s actually bright then they work fine). After Paolo Salvagione’s comment about using a smaller motor to rotate the device, it occured to me that I could use the vibe motors in two directions to create movement that follows the sun:

 

****

Ordered this motor: 

Here is a new design with (human) adjustable tilt. It has more of a “pro” vibe. The motor adds 5 euros to the total cost of the machine bringing it up to 15 euros:

****

Looks like the trick with the light sensing is just to put the photodiodes behind the board so that the shadow cast by the sun creates a clear preference for one side or the other. They can be bent around a little bit to be perfectly tuned but it also adds a bit of idiosyncracy to the ‘bot. So it doesn’t appear that I need a trim pot for this option. I’m not sure how to create the same contrast with the solar panels as putting either in the shade is obviously not a good idea. Pointing them in different directions creates some difference but not a great deal.

****

I’ve redone the circuit for the 74AC240 and make it more compact:

Here is my next design with the smaller DC gear motor. I’m imagining a soldering a pin to the PBC in order to attach the pivoting arm to it. Otherwise the issue is how to make this attachment without creating a whole frame and bumping into components etc. It has a small M2 bolt to fix the print to the motor and to adjust the angle:

I’ve made a cleaner video of the first prototype:

Dual Solar Tracking Part II

Continuing the project of making a small solar tracking device.

****

Idea to simplify the circuit drastically and make the 3D model a bit more robust and less fragile so it is far easier to assemble and won’t topple over (while hopefully maintaining some elegance…) 

-Battery-powered (and possibly solar recharging through very simple circuit):

 

plus Attiny with two steppers only powered directly from output pins (max 40mA and danger of kick back which might be solved with diodes) and no light sensing – just the almanac algorithm for sun following. *

*(Remember you can test the stepper resistances to know which are pairs!)

Tried powering a stepper directly with an Atmega using the Stepper library in Arduino with a bunch of different step and speed values – if it turns at all it’s extremely weak…So this doesn’t appear to be an option.

Tried powering an atmega328 directly to cap and solar panel through diode, in medium sun there is no action. With bright sunlight it manages to power up despite blinking a blue LED every secon. I could try with the sleep timer I recently acquired (https://www.adafruit.com/product/3573). Or maybe a simple sleep code will be enough. This seems like a viable option which would simplify the circuit considerably.

Another cheap and simple option is the ULN2003, but this requires 5V to function unlike the low power DRV8833 I have. 

***

Tried driving the stepper gearmotor chain drive and it moves very smoothly and almost imperceptably. 

I dug up some DC DVD raft drives, they are nice mechanisms:

The black rack was attached to the raft. 

I tried powering these with Wilf’s SPSH circuit and the bearbones solar head and they were too big a motor to be powered unfortunately. I could still try to increase the 1381 trigger level with a resistor though…

I’ve redesigned the microchip version of the board to make the wiring to the stepper much easier this time. I’ve also added two caps to smooth out the motor supply. 

And here is a more robust version of the previous two stepper, this one has two parallel bars, a more robust hinge, and the lower bearing is encased completely for more stability hopefully. I am also getting rid of the lead screw plastic piece and trying to replace that part with a thin metal rod. In general it’s simplified and a bit thicker all around :

I am using a dremel to clear out the holes before inserting things and this is reducing shattering of the more fragile white resin. 

The bottom bearing:

Part of the solar panel hinge:

Only one of the two stepper drivers worked on this board but I haven’t found the issue yet…I wonder if back reverse polarity I destroyed it by accident or over heated it during soldering. I’m going to replace it with a fresh one and see if that changes anything.

 

Here’s the assembled machine:

Here is a look at some of the technical details:

 

A different panel orientation option: 

Comparing the two versions (the newer is far more compact and stable but less playful and off-beat/asymmetrical):

Check out the angle range, it’s better than I expected!

ERRATA:

  1. The idea of putting a pin accross to act as the lead screw is not working with only one side screwed in. AND the lead screw platform is impossible to insert into position (I had to break it in half and glue it back together once in position). I should definitely not try to go under the lead screw, with the nut that holds the pin, it actually makes contact with other nuts holding the whole linear rail assembly. I think I should go back to integrating the existing plastic lead screw – aesthetically it adds more flavour and asymmetry.
  2. The part that attaches to the panel should be one connected part because this gives more surface to attach to and more rigidity. (X)
  3. There is a volume which enters into the bearing socket that I needed to remove with the dremel. (X)
  4. The three bottom holes for screws are not evenly spread out around the circle. (X)

POSSIBLE CHANGES:

  1. Tensioner for bottom chain or larger bottom gear?
  2. The top hinge is too symmetrical for my liking but otherwise it’s super stable.
  3. Transparent resin is definitely nicer.
  4. The bottom nut needs a tiny bit more room, but it just works.
  5. The bolts are hitting the bottom stepper gearmotor.

Here is a new version which solves the errata, but it looks hideous:

I am considering returning to a one bar setup. I am also considering how I can make one version of this device that will work for the different linear actuating steppers and the different rotational motors (the micro steppers and DC gear motors have the same face plate thankfully). The top and bottom of device are also not connected (so varying heights of linear drives can be accomodated). Should one single design be able to work with belt drive or chain? I think I should now focus on producing a bunch of these.

Here is how the little plastic parts that act as lead screws work:

 

There are all kinds of shapes but in the end they all appear to have one main screw location and a bunch of other nibs and slots to help with alignement. I can include a sliding slot for the main screw in the 3D print but I may use a dremel to adapt it to different nib locations. 

I’ve revisited the version 1 and have made the following changes:

  1. I’ve kept the more robust base from version 2.
  2. I’ve revised the lead screw plastic part holder and made the print compatible with the highest number of these peices and allowed for longer stroke.
  3. I’ve kept the magical setup that allowed for a great variation in the panel angle.
  4. I’ve kept the circular base which is more stable and made a larger base gear so it looks more stable. (The pitch of chain I am using is 0.1227″ https://www.mcmaster.com/miniature-roller-chain-sprockets/pitch~0-1227/)
  5. I adjusted the motor so the bolts are no loner hitting the bottom stepper gearmotor.

 

****

Wire management:

I like the ribon wires from the CD drives and the mini locking sockets and plan to use them:

The top option seems sensible.

Here the bottom motor ribbon is going to be super stretched when the panel is at full extension in angle…

I like the asymmetry of the second option, it implies that the lead screw and hinge action is taking place on one side and the electrical connections on the other side.

(I’m just realizing that some of the ribbon cables that come with the stepper linear drive are not very long + the brown/orange doesn’t go super well with the white. Should I replace those cables with white ones so that everything is the right length and homogenous?)

 

There is also the possibility of folding the ribbon cable…

I’m trying to find this product (it seems to be called “flexible flat ribbon cable”) but not having luck on Farnell or Mouser (*correction: https://www.mouser.fr/ProductDetail/Wurth-Elektronik/687606050002?qs=qR1qlUC5%2FYSp8nXHAtNchQ%3D%3D) …Here it is on Ebay and Amazon:

The other option is to harvest wire from the old CD drives I have, the wire lenghts seem to vary from 8-11cm.

Some solar panel options:

 

****

Next version sucesses:

orienting parts so that the supports don’t touch faces that will be seen is a good idea, it saved the bottom platform from pockmarks.

Errata:

  1. The main issue is the lead nuts. They are massive and therefore reduce the stroke considerably. Most have a setup where they push against the leadscrew and twist the sliding cam which is now only fixed to one rod.  I should try to design the nut myself, if the solar panel is in the middle it is hidden in any case. The other option is to find another one in a million lead nut that works like the one in version one where it doesn’t push against the cam / use two bars. (X)
  2. Somehow the ratio of arm lengths is producing a totally different range of angles, mostly in the negative direction! (X)
  3. the layer on top and below of the bearing is too thin and comes out wavy. (X* I did the top visible part but not the bottom).
  4. missing a subtraction around the collar of the bottom stepper motor shaft. (X)

Possible changes:

  1. all black hardware would be nice. Or perhaps all white?

******

Modeling the lead screw:

The threads themselves:

I want it to be possible to adjust this thing so I am planning to use a stack of washers to accomplish this. I am also adding a notch in the purple volume to prevent the green volume from rotating. It should also mean that the green volume can be made to accomodate different threads and the purple volume will still work regardless (i.e. it’s modular).

The backside leaves space for a nut to fix the green piece in place at the right height.

I’ve also adjusted the angles to match the version 2 as exactly as possible this time:

Here is the finished version 3:

Some quick ideas about how this project could be displayed in an expo:

1. I can make a bunch of solar critters that react to the sun in different ways (sweeping in circles, following the sun but staying in place, making sound by tapping the ground or playing a song, etc.). This is the kind of ludic, “diversity of nature” bio-inspired option. The robots are indifferent to one another but occupy the same space. I’m not sure how to chose the materials but maintain difference/cohension of the group but presumably I could pick a kind of 3D printing and use the same motors.

 

2. Make one such critter (like the sun follower) and create an array of them in a given space and watch the group effect of their behaviour. This is kind of obvious but at least it’s abstract and sober, hopefully fitting in my portfolio with my other more abstract/representational work. It would also be easier to mass produce one design than to make a bunch of one-off designs I think.

And here is the BOM so far:

And here is the newest build:

ERRATA:

  1. The lead screw does not work. It is not perfectly aligned with the threaded rod and the system for holding it tightly in place is not working. I think I need to put the lead screw on the bottom side of the threaded rod and have a tensioning mechanism on the front (accessible) side.
  2. The angles are still wrong. If I make the top arm (that is glued to the solar panel) shorter I think it will improve.

I’ve put the lead screw on the back of the threaded rod and inserted alignment rods and increased the borders to hold the top piece in place:

****

The solar panel angles are fixed! With two of the threaded nut sides making a sandwich it does actually work as a lead screw nut (even though it really doesn’t look nice) !

***

Thoughts from artist Paolo Salvagione:

  1. Make a power budget (what does everything i.e. steppers, microchips, drivers use when not on, when on)
  2. Run motors 24/7 for weeks before to test that nothing falls apart.
  3. Replace bolt hinges with flanges or miniature bearings from McMaster Carr. (The smallest available at a reasonable price is 5mm OD no flange).
  4. Try pulling up everything to the top beneath the board and alternatively pushing everything else to the ground to create a sunflower.
  5. Think about the center of balance of the machine and how you can place it directly over the pivot point (or move it there with weights).
  6. What kind of choreography would I like to see here.
  7. Alibaba has super inexpensive solar panels that look great.
  8. Could the array relate to different light sources which exist in a kind of solar system around the plinth.
  9. How can visitors experience this piece at different distances (“layers” of experience)?
  10. Medium-runs of a finished design are easier than making a ton of one offs or mass producing.
  11. It’s possible to order flexible PCBs from PCB Way.

****

Some thoughts on the layers possible:

I have found a few 10mm OD bearings and will redesign the arm portion with these:

I’m not totally satisfied with the bearings in the design (McMaster has perfect 5mm bearings that are reasonably priced but they don’t ship out of the U.S.).

****

Calculating the balance point with help of this site: https://www.school-for-champions.com/science/gravity_center.htm#.X2B-cFUzaUk

Calculating CG of weights 

CG = (aM + bN + cP)/(M + N + P)

Seems like I should try to keep the solar panel light in general (under 12 grams?), but that I have the option of adding some weight above the stepper in the rear. In the other axis I can shift the solar panel a bit to the side to compensate for the weight of the bearings in the arms. 

 

****

New version with arm bearings:

It was hard to attach the solar panel to that arm model so I switched it for one with mini bolts:

   

I don’t like the look of the three wide and narrow bearings so I am trying to hide one under the panel and switch up the second by putting the black bolt through it. One of these only would look great but three is too much.

 

A new design with McMaster 5mm bearings (I can in fact order them it would appear). In one I keep a single large bearing and in the other all the bearing are small:

Making a third prototype to test the following things:

  1. Durable resin for everything but especially for the lead screw.
  2. Adding flanges to hold the current bearings in place.
  3. Slight tweak to the currently improvised lead screw design.
  4. Fix angles again with shorter arm.
  5. Hiding the other bearings a bit under the panel.
  6. Making a third so that I can begin testing the “swarm” effect of the robots actually moving.

****

I began two stress tests based on Paolo’s advice:

Some things to note:

  1. These are so much fun, people visiting see what you’re doing as Paolo suggested!
  2. It fights anxiety – you know if it will work or not.
  3. Working for 1 minute is not the same as working for two weeks 😉

Unfortunately there is a serious issue: The linear drive is drawing 600mA at 5V to move up and down…I should try to mess with the steps and speeds to see if I can get this down. The rotating motor is drawing less than 150mA. 

Looking on Alibaba, the most popular size of smaller panel is 156mmx156mm.  But also found some 47×47:

and some 55mmx14mm

37x21.8mm 6V 2mA outdoor used Thin Film Amorphous Silicon Solar Cells for Outdoor Products

37×21.8×1.1mm 

Here are the best links I’ve found so far:

https://www.alibaba.com/product-detail/55x14mm-3-0V-7uA-dim-light_60585863880.html?spm=a2700.galleryofferlist.0.0.43be4630X6CXwJ

https://www.alibaba.com/product-detail/Dim-Light-Amorphous-Silicon-Thin-Film_208238751.html?spm=a2700.details.deiletai6.5.561929devzX1BP

https://www.alibaba.com/product-detail/3V-10uA-Dim-Light-Amorphous-Thin_62187655652.html?spm=a2700.details.deiletai6.1.561929devzX1BP

https://www.alibaba.com/product-detail/37×21-8mm-6V-2mA-outdoor-used_60506651563.html?spm=a2700.galleryofferlist.0.0.2430367cO11E7R&s=p

 

I sent my first email: 

Hello,

I’m a research engineer at the Universite of Paris Sud in France and an M.I.T. graduate.

I’m working on a low-power solar follower product and reqiure small cells like yours to create a series of panels (with each an array of 5×2) to combine with an energy harvesting IC.

I am interested in your product and would like to request a sample if possible to test with my setup.

Thank you ,
Jonah Marrs

*********

Easy stepper motor driver can drive both steppers at around 150mA at 5V with no load. 

The DRV8833 with correct step and speed settings can drive the linear with the plastic lead screw found in the CD drive at around 360mA but has a super high idle current of 600mA. It gets super hot as a result. The DRV8833 cannot drive my lead screw setup however… Basically there is too much friction in my lead screw design currently. So, the conclusion is that it’s possible to drive this thing if I put the driver to sleep and I use the existing lead screw.

I am leaning towards using the found CD drive mechanisms (because they are perfectly made to minimize friction etc. already and look super cool) and add a second bar parallel to the first to improve stability and compensate for the rotating that the plastic lead screw wants to do.

I’m also adding another bolt to the bottom angle bearing, and looking for some 3mm bushings to add to the sliding portion. Here seem to be the two primary options:

The side by side bars on the left are less flexible with different found lead screws as the bolt location can’t move much to either side. It also makes the front part flatter and longer, whereas the bar behind makes the design feel more three dimensional and compact. 

I prefer the bar behind. 

Bending joints options:

I like the asymmetry of not having the top and bottom joints unaligned in elevation and in plan views, it feels more dynamic and optimized. I like the bottom bearing being centered with the cam. 

Hopefully this version will allow me to do some stress testing with the tilt mechanism.

 

Here are the parts laid out:

The assembly turned out well:

 

ERRATA:

  1. The lead screw is a tiny bit too high above the threaded rod, I had to carve out some material with the dremel…
  2. The elbow joint connected to the cam can’t work with a captive nut the way I originally concieved but it can work with the cap of the screw in the place of the nut.
  3. The set screw for the sprocket needs to be almost flush with the sprocket surface to not hit the bearing squeezing screw. The bearing squeezing screw between the parallel bars needs to come from the top not the bottom or else it interferes with the chain. 
  4. I think I need to shift the two bolts that hold in place the bottom motor 90 degrees. And I may need to add a little circular band to keep this motor straight.  A tiny drop of hot glue solves this…
  5. The solar panel surface is not flat but tilts inwards.

I got the test set up working again with two Easy Stepper Motor Drivers (with Enables and 5V+ connected also) this time. Now the bottom motor is driving 100mA and the linear is pulling 200mA. Both are cool to the touch. However, there is a little bit of power lacking for the linear lifting motor and it is skipping some steps. Switching to 1/4 instead of 1/8 microstepping, and making sure all the bearings are set up smoothly, appears to mostly fix this though.

Some experiments taking nicer photos:

A with and without solar panel gif:

*****

I’m doing a next design based on the observation that the motor is struggling to pull up the solar panel and that the weight could be repositioned closer to the center of gravity and rotation axis. It’s more sunflower like, and the lead screw is now exposed as in version one. Nicer balance in terms of the bending joints which now aren’t all on the same side. One of the three bearings is hidden so the emphasis is more on the two side ones now. Far more sturdy rotation mechanism for the solar panel so no more warping and bending hopefully. The arm will have to travel far less distance to change the angle of the solar panel also.

This experiment is interesting to me because it’s an attempt to move towards a more robust design while trying to keep it visually interesting and maintaining the attention to form.

 

I adapted it for a mirrored version of the linear drive and new lead screws (it wasn’t too hard to do). Now I have right and left handed machines:

This is interesting as it shows how easy or not it is to adapt to the repurposed CD drive mechanisms with the current design and how much variation can be created organically. 

***

 

It looks like I should go with white Rigid resin and that I should use bushings for the sliding portions so no part of the print has friction.

These appear to be the key characteristics of the lead screw/nut setup.

****

Adding some grease to the rails:

*****

Here’s the tall version:

It has great tilt range.

It feels much taller and more slender. It also looks far more like a sunflower. It’s also lost its animate / cuteness quality that comes from being compact and now feels more like a machine. It does make more sense in terms of weight distribution, however.

It proves that the idea of adjusting for found CD drives works in principle. 

V.4 ERRATA:

  1. The Durable resin is too flexible to make rigid longer parts. The whole assembly is flopping all over the place.
  2. I need to modify the central solar panel hinge – it’s not possible with the hardware I have to make it function properly. Because the tilt arm pulls from the side, it has a tendancy to tweak the central hinge. I could use the large bottom bearing up top?

****

The new version features a pole that pushes up to tilt the solar panel, and lets the panel rotate down when it descends. This means fewer bearings and maybe less strain on the linear actuator stepper motor:

I’ve redesigned the control board. It now has a nicer spacing between the motor driver out pins and doesn’t have any other wires nearby to get in the way of these pins. It also has the motor driver sleep pins connected to the microchip, and can drive two steppers instead of one stepper and one DC motor as with the previous version. It also has more noise attenuating caps:

I am also considering using an Arduino Nano with DRV8834s and a mini lithium ion just to get this prototype running!

This works but it’s very heavy with the battery packs. I may need to glue the bearings in place or work with a more robust design for this phase.

 

I’m using the StepperDriver Arduino library and this is what my loop looks like:

if (analogRead(A0)-analogRead(A1)>threshold)
{
stepperTop.move(-MOTOR_STEPS*MICROSTEPS);
}

if (analogRead(A1)-analogRead(A0)>threshold)
{
stepperTop.move(MOTOR_STEPS*MICROSTEPS);
}

if (analogRead(A2)-analogRead(A3)>threshold)
{
stepperBottom.move(-MOTOR_STEPS*MICROSTEPS);
}

if (analogRead(A3)-analogRead(A2)>threshold)
{
stepperBottom.move(MOTOR_STEPS*MICROSTEPS);
}

 

And here’s the new print:

****

Just discovered why I may have been having issues with the DRV8833s…Their max soldering temperature is 260C, I have been using 300C!

****

I tried to get a full prototype running with the Arduino breakoutboard version but it’s surprisingly heavy and both attempts were unsuccessful. The second:

Without the weight of the circuit board everything is fine however:

 

I think I may have to admit that this thing is too janky to work beyond as a quick video. 

 

*****

Meanwhile I’m working on a DC prototype of the more complex 2DOF design:

 

The idea here is to have 2 1DOF solar engine circuits + a dark activated pummer circuit. The machine would then spend its days searching for the sun and charging up a bigger capacitor to then blink at night like a lighthouse. I’m not sure if I should make the blinking synchronise with other nearby blinkers using this circuit:

https://www.instructables.com/Synchronizing-Fireflies/

One DC motor (controlling the tilt) is so slow it’s barely noticable at all while the other one swings the machine round dramatically. The design has less magic than the servo version but is far easier to control and has no issues with the weight of the solar panels. 

 

Robot Arm

Here is the final product:

 

 

1 Common robot arm configurations | Download Scientific Diagram

After the relative success of the foam cutting machine, I would like to build a medium-sized robot arm which can actually be a useful tool in the lab and not just a toy.

The main questions appear to be: how to increase the torque of the stepper motors? Should we make a classic robot arm or a Selective Compliance Assembly Robot Arm SCARA?  Should the parts be 3D printed or CNC milled (or a combo)? and, Do I already have the parts necessary or do I need to order them in which case how much should I order?

**********

Stepper torque options:

1. Use our super beefy stepper motors. Unfortunately, none of the other hardware (like belt sprockets) fit the diameters of the shafts.

NEMA 34 Stepper Motor (6A , 12 Nm , 151mm) | DIYElectronics

2. 3D print a planetary gear or buy one:

(but these make the front of the stepper bulky and a bit ungainly)

3. Get a large timing belt pully with a short belt drive: (unfortunately we don’t have anything like this lying around the lab).

4.  3D print a large gear to turn directly with the stepper:

A different concept that involves a motors not all at the base:

**********

SCARA vs. Conventional robot arm.

 

Building SCARA Robot Arm pick and place using vision system - YouTube

YK400XE

#SCARAs fold up easily and are faster for certain tasks than conventional robot arms.

 

pyBot: OPEN SOURCE and 3D printed Robotic Arm controlled with Python

Custom SCARA printer finally taking shape. : 3Dprinting

Scara arm solution

A Desktop SCARA Robot using Stepper Motors

298 Best CNC images in 2020 | Cnc, Diy cnc, Cnc machine

But there are some neat conventional robot arm designs out there too:

*******

CNC milling vs. 3D printing:

CNC milling some parts (like the large gears) seems possible:

Nylon and ZMorph CNC PRO Milling Toolhead

But I also need either to buy a large bearing or to make my own bearing…Unless I make a geared slew bearing:

Single Row External Gear Slewing Bearing China Manufacturer

Here’s a cool guide on designing gears: https://lcamtuf.coredump.cx/gcnc/ch6/

Some DIY slew bearings:

Project | Mammoth ARM | Hackaday.io

A 2.5D Slew Ring | Hackaday.io

***********

Robot background information: http://www.societyofrobots.com/robot_arm_tutorial.shtml

Cool tutorial includes info about DOF, calculating torque for each joint (fewest joints possible with shortest lever arms the better): http://www.societyofrobots.com/robot_arm_calculator.shtml

Some simple arm linkage ideas:

Homemade Scara Robot Arm DIY Robotic Frame Projects Laser 3D Printer Chassis Draw Arduino Control d - YouTube

3D Printer Technology and Innovation | Desktop cnc, Robotic arm diy, Diy robot

**********

And these Five-bar linkage machines (aka Parallel SCARA robots), they appear to be known for being super fast:

https://en.wikipedia.org/wiki/Five-bar_linkage

Homemade Scara Robot Arm DIY Robotic Laser 3D Printer Chassis Draw Arduino Control Frame Projects 2 - FutureTribe.Me

SCARyllA: Dual (parallel) arm SCARA laser engraver build

ÉTS : Laboratoire de commande et de robotique

Related image

Lightning-Fast SCARA Robot Prototype by Proto G - Hackster.io

**********

For the end effector I think either air pressure or electromagnet:

Vacuum End Effectors VEE

Robotics Industry Insights - Latest Trends in Intellig...

************

Some early models:

With only two rails (I’m not sure if this is sufficiently stable or not as many designs have 3 or even 4 rail):

Similar but with a larger motor at the bottom and less ugly mounting plate. 

A completely different SCARA design, I like the silhouette but it would involve tons of cut planar material that would need to slide into together and we might not have everything on hand to make this either: 

Quick attempts at 3D printing planetary gears:

https://www.thingiverse.com/thing:2114390

https://www.thingiverse.com/thing:3231908

(interesting belt option here: https://www.thingiverse.com/thing:2911407)

Using the 0.8 nozzle was not ideal and none of the pieces fit properly. I would love to try this as a cnc cut project but I think it would be highly technical and difficult and at the end would end up in a tiny box. (I’m going for medium scale machines at the moment not tiny intricate things).

We have 12mm HDPE in white and blue in the lab, I’m going to first 3D print then mill it. 

I’ve come to a compromise with the design. It will give me the opportunity to design with a Nema 23 a complex peice (geared slew bearing), to work for the first time with a 5 linkage parallel robot design, to CNC mill HDPE for a more robust machine, but also builds on the syringe pump linear actuator and the foam cutter designs. Most importantly, I have all the components I need to build the full prototype already in the lab. 

I added hardware to this model to make sure everything makes sense:

*********

Developement of the geared slew bearing:

Outlined this drawing in Rhino and then applied it to a circle:

To make everything fit (increments of 2mm) I changed the size slightly of the gear:

 

Here is the first prototype:

Here is a section showing the bearings cut through and how two layers of 6mm HDPE should come together to make the bearing. After assembling we’ll see if .1mm was too much spacing between the bearing and the walls, and also if there need to be two rows of 4mm bearings.

 

*******

Here are the 5 bar parallel robot 3D printed parts (view from underneath):

A combination of nuts, washers, 16mm bearings and socket shoulder bolts:

There is an offset in order to make everything work on the stepper motor shafts:

 

*****

With the final additions here is the final machine:

Here’s the 3D print file with all the parts: 

Here is the kit of parts (minus the parallel arm rods):

The geared slew bearing assembly is tricky because the bearings want to fall within the inner moat.

Adding the top bit:

Finishing it off:

Here is the drive mechanism with an idler I added:

Assembling the parallel robot arm components:

Hammering in the bearings caused splitting in the print…

I sawed the metal bar and deburred before assembly. 

The top threaded rod motor assembly (I broke one side hammering the nut in a little too vigorously)  

Despite checking and rechecking I somehow forgot to put holes in the middle of the rod bearings (!)

Here’s the linear actuator assembly:

 

With the parallel arms attached, just waiting for the base to finish printing:

With the base:

 

Errata with the bottom part of the robot:

-impossible to tighten hex nut to fasten gear to bottom motor axel. (Added slot for this purpose)

-not nut subtractions to help hold bolts which fix geared slew bearing to base plate. (Added captive nut subtractions to bottom of base plate)

-I subtrated a cylinder from the base for the motor gear but this makes no sense as it rotates around and does not stay fixed. (I filled this in)

-With current arrangement the belt between the drive shaft and geared slew bearing was loose. (Either I add a spot for an adjustable bearing or I change the location of the motor to pull it further away…I chose the latter).

****

CNC milling:

The top motor and rail mount:

I replaced one part of the 3D printed robot parts at a time:

The middle component:

Everything fits together nicely!

And here is the final result:

The CNC mill using HDPE is extremely fun to use. The only part that is not easy to make is the bearing assembly. This I will print in durable white resin on the Formlabs.

    

Medium-sized CNC Foam Cutter (with Léon Reboul)

Here is the finished product:

 

And here is a quick video cutting foam:

 

Another video showing the stage testing:

 

 

Here are the files on Thingiverse: https://www.thingiverse.com/thing:4428184

We’ll be harvesting parts from an old Ultimaker 2.

The stuff we plan to use:

Based on what we found, we plan on making two threaded rod actuators and two belt-driven actuators.

Here is the prototype of the linear threaded rod actuator:

Here is the prototype of the linear belt-driven actuator:

Here is the prototype of the entire foam cutter assembly:

 Here are all the parts 3D printed:

Here are the 3D printed parts along with the hardware:

Here is the belt drive assembly:

 

Here are the two axes completed:

Here is the first of the two linear actuator drives:

Slight differences between the two based on different hardware but essentially the same:

Here is the full assembly minus electronics:

The electrical connections to the TinyG:

All plugged in and ready to go:

 

Using the webpage CNC controller Chilippeper :

Running local JSON script to allow the website to access the COM ports, if I understand correctly:

 

Chilipeppr Configuration (https://github.com/synthetos/TinyG/wiki/TinyG-Configuration-for-Firmware-Version-0.97):

To change the Motor – Axis assignment in Chilipeppr:

$1ma=0 Maps motor 1 to the X axis
$2ma=1 Maps motor 2 to the Y axis
$3ma=0 Maps motor 3 to the X axis
$4ma=1 Maps motor 4 to the Y axis

To assign the same travel per revolution for axis 4 as for the other 3 axes:
$4TR 1.25
To swap polarity of a motor:

$1PO

  • 0 = Normal motor polarity
  • 1 = Invert motor polarity

To set X axis minimum and maximum end stop limit switches (the switches connect GND to XMIN or XMAX on the Tiny G).

$XSN 3 and $XSX 3

To change the distance for every movement of 1mm:

$1tr VALUE

To change max feedrate in X:

$xfr

*************

Here is the video of the machine making its first moves:

**************

Here is a version two fixing some errors in the 3D modeling:

Linear actuator redesign (forgot to subtract the motor and threaded rod previously):

Here’s the finished belt-drive assembly:

I reprinted this part with 40% density instead of 20% (which broke last time when I tightened), corrected the diameter of the rods (which destroyed the rigity of the actuator), reoriented the embedded nut, and used shorter bolts:

Also 40% instead of 20%:

This was a bit tricky but using two bolts with washers I replaced the hot glue to fix the belt in place. 

I corrected the orientation of the holes and the two actuators line up perfectly:

Here’s the final assembly version 2:

 

*************

I’ve added some limit switches and have a preliminary setup for the hot wire cutting fixtures:

**************

Here is the first test cut:

 

Here’s what it looked like on the software side:

 

I used CAMBAM to take in a DXF and output the Gcode. 

I had to additionally make everything related to the Z axis zero, and set the start point.

DIY Centrifuge

Based on Hackteria’s DIY Centrifuge (https://hackteria.org/wiki/Hacked_Hard-disc_Centrifuge)

Controlling a Three-Phase DC Brushless motor (BLDC) of a Hard Drive primer: https://www.monolithicpower.com/pub/media/document/Brushless_DC_Motor_Fundamentals.pdf

Similar to a stepper motor (except a BLDC is meant to run smoothly not in steps) but with three stators (if it’s an inrunner, an outrunner has the permanent magnets around the shaft): 

What are Brushless DC Motors | Renesas Electronics

 

At the top are the signals we need to generate with signal phase 120 degrees offset (steppers are typically two phase with 90 degrees apart):

BLDC Motor Control With Arduino, Salvaged HD Motor, and Hall ...

I’m using the SN754410 Quadruple Half-H Driver IC based on this tutorial: https://elabz.com/bldc-motor-with-arduino-circuit-and-software/

Here’s the circuit breadboarded (motor connection not shown) with a pot to change the speed:

Here is the scope capture of the sigals generated:

This is the 3D file I downloaded: https://www.thingiverse.com/thing:2539744

Here’s the 3D print with two 1.5ml Eppendorf tubes screwed on to the BLDC hard disk motor. 

I had difficulty distinguishing between which of the three wires were connected to coils and which on wasn’t and got inconsistent resistance measurements. My current thinking is that the motor was damaged and is not working.

Testing with another kind of BLDC and still not working…so is most likely my circuit?

EWOD (electro wetting on dialectric)

This project is based on Gaudi Lab’s OpenDrop (https://www.gaudi.ch/OpenDrop/)

Here is the github for Fablab Digiscope’s iteration of the project: https://github.com/merlinmarrs/OpenDrop

We don’t have high voltage MOSFETs so we are using relays instead. In parallel we will be sourcing the components to make the high voltage power supply using a boost converter that takes 12V as input. In the meantime, we will be using a transformer that sources 100V directly to the board to test functionality. 

Here is the board cut:

To supply the minimum 100V necessary, I found this high voltage boosting circuit here: https://www.multisim.com/content/dUPNxLKfTuK3sYfGNjNxNg/9v-to-100v-boost-converter/

With what we have in the lab, it’s peaking at just under 80V. 

Testing the relay:

Testing the relay with a motor and 9V battery:

Here is the first full prototype:

 

What we need now is some hydrophobic dialectric like Teflon…

Fever monitor

This device is intended to be installed within the 3D printed forehead mount of a visor. 

It’s being developed at this github: https://github.com/merlinmarrs/Fever-Meter

The top board is a boost regulator taking the 2V from a pair of miniature backup batteries, and the bottom side is an attiny85 with I2C temperature sensor and indication led. 

This project necessitated the use of rivets. I used a dremel to make a hole in the board then inserted the rivet and gave it a tap with our riveting tool.

The results are relatively clean:

IR thermometer with POV display

This contactless temperature sensor has a POV display for the temperature readout. 

Here is the github: https://github.com/merlinmarrs/POV-fever-meter

Here is what it looks like in a dark room with long exposure:

The plan was to have the device spell out the message in reverse after displaying it normally to allow a certain frequency of waving the wand back and forth to display perfectly. Alas…this does not work well currently.

I am still waiting for the IR temperature sensor to arrive in the mail.

Dispositif Désinfection

Developed by Fablab Digiscope.

A board to sense the temperature and illumination, and act as an interface, inside a disinfection device:

https://github.com/merlinmarrs/anti-viral-dispositif/

A main board and secondary board to control a disinfection chamber based on this tutorial: http://www.needlab.org/face-masks-disinfection-device

Here is the BOM:

Standard components:

7 segment display x2 595 Shift Register x2 LED x 2 Photocell Piezo Atmega 328p micro-swith (CHECK MAX VOLT + AMP RATING)

exotic components:

lampe UV-C à Amazon.fr:

https://www.amazon.fr/Germicide-Ultraviolet-st%C3%A9rilisateur-Submersible-radiations/dp/B07Y82SM36/ref=sr_1_4?__mk_fr_FR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=uv+aquarium+sterilizer&qid=1587383305&s=hi&sr=1-4-catcorr

  1. MLX90614 (pas en rayon a Mouser, Farnell, Sparkfun, Polulu ou Adafruit) à Digikey (ou c’est “hors prix”) ou Amazon.fr:

https://www.digikey.com/product-detail/en/melexis-technologies-nv/MLX90614ESF-DCA-000-TU/MLX90614ESF-DCA-000-TU-ND/2025323

https://www.amazon.fr/MLX90614ESF-MLX90614ESF-BAA-000-TU-ND-thermom%C3%A8tre-infrarouge-compatible/dp/B07JBKM2K3/ref=sr_1_1?__mk_fr_FR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=MLX90614&qid=1587470750&s=hi&sr=1-1-catcorr

 

 

 

Still waiting for the temperature sensor to arrive in the mail. 

Syringe pump mechanism + electronics

 

This is the stepper motor driver design we are hoping to use to control a syringe. Here is the PDF describing the assembly: etapes fab venti v2

And here is the github repo:

https://github.com/merlinmarrs/FabVenti

 

This is the syringe pumping prototype I developed. It uses 8020, a NEMA stepper with built in threaded rod, NEMA motor brackets, and linear bearings. The rest is 3D printed and uses M3 and M4 screws. 

Solar Electronics Primer

The goal of this primer is to introduce people to mini DIY solar energy applications.

New solar product I just found out about: 

Solar Digital Calipers

                  

Fab 15 Part VII

Here are some videos of the current prototypes:

 

 

 

 

I want to focus this project on the design of the 2 axis rotation mechanism. The electronics and code side has already been explored and I can’t offer anything new here as a designer.

(I’ll abstract the sensing and radio side of thing for a now and design the PCB to be sent to manufacture later. This will be a good exercise in applying the new PCB design best practices that I have since learned and for overcoming the limitations of PCB making in the lab. I could imagine this board having a compass and accelerometer to find out its own direction, and possibly an wifi connection to send its data to the internet.

To simplify things further, I could think of this design as an indoor weather station. Instead of the tpical arduino inside a plastic box though, this project would emphasize the dynamic quality of solar energy, turning solar tracking into an exciting technical spectacle. The design would make reference to off-grid technology and thereby embody the mythical appeal of the power-autonomous and the off-grid (tiny house movement, prepper phenomenon, etc.).

*************

I’m inspired by weather buoy design:

 

And also the possibility of some kind of Wes Jones inspired multi solar panel actuated louver system:

Louver Dampers / Industrial Dampers • Kelair Products Inc.

It could look like the MIT solar panel project but it would have a lower center of gravity and be motor controlled.

Hyperstealth's "Declipse™" Shadow Reduction Technology Solves MIT ...

Some quarantine sketches:

*************

Problems with the previous prototypes:

V.1

Top heavy and always falling over.

Middle connection to ball bearing not sufficiently robust

Nothing keeping motor on track, it lifts up off the gear track.

Center mast not easy to fix in place.

V.2

Will topple over in certain positions.

Tilt cannot rotate 360 and is holding a lot of weight.

No way to tell exactly what position reached.

****************

V.3 Hinge tilt + 3D printed bearing with motor mount integrated

The hinge will be based on this idea from https://www.generationrobots.com/en/402702-pan-tilt-kit-for-pixy-camera.html:

Some detail shots of the assembly (from https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:assembling_pantilt_mechanism):

Here is the one sided threaded bracket:

https://www.sparkfun.com/products/10228

Angle Bracket - 4-40

Here is a 3D printed version: https://www.thingiverse.com/thing:978300. I would be replacing the servo with the DC gear motor and changing the bolts:

And this is how the servo arm fastening works:

In combination with this is the idea to design a completely custom rotation system. This would combine Paolo’s 3D printed bearing mount (https://www.instructables.com/id/3D-Printed-Bearing-with-Driven-Miter-Gear/) with DIY stepper motor coils:

Image result for paolo 3d printed bearing

3D Printed Bearing With Driven Miter Gear

And these are two 3D printed stepper motors based on wrapping wire around nails and using rare earth magnets. I could also incorporate feedback by printing stripes and counting them with a line follower.

The only problem appears to be the voltage required to power these motors which seems to be between 5V and 20V. Perhaps I could take some industrially made coils (which would be presumably more efficient) and reuse them. Like from the inside of a real stepper motor:

Image result for 3d printed stepper

The magnetic field of a coil appears to be based on the coil density (number of turns per length of wire), the material in the middle of the coil (like iron), and the current passed through. I would need a dense coil if I didn’t want to drain the caps.

I could also work with small stepper motor linear actuators like this:, but then I would need to convert linear to rotary motion:

Image result for mini stepper motor

As for the code:

https://www.hindawi.com/journals/js/2019/3681031/

According to the above article, loading the Astrologer’s Almanac onto a sensorless microchip appears to be even more efficient than giving a microchip light sensors in the classic approach (https://create.arduino.cc/projecthub/ioarvanit/dual-axis-solar-tracker-panel-with-auto-and-manual-mode-41cfd9).

Code has already been optimized for arduino: https://pdfs.semanticscholar.org/ffd3/bb8b5e85c796da0ae3eac3be11117291289f.pdf

*****

Here is the next version of this design:

The thinking is to look around and find existing parts of medium to high quality in the lab, and design something which works around those preexisting parts. (I have the gears, the chain, the 3mm rod, and the ball bearings. The bearings we have don’t have 3mm inner diameter so right now they just turn around a hole in the 3D print / CNC milled axle holders. 

Here’s a right angle design with only one bearing and less hardware (there may be a weight distribution argument for one of these assemblies):

Remaking the gear (less improperly this time) with Sweep1 and scaled outline which I bent into a circle:

Here’s the model ready for print:

lazy explosion:

The 3D printed parts:

The begining of the bearing assembly:

The alignment was impossible to get right here:

 

 I ended up hacking together something with Paolo’s bearing and some old prints. After some sanding and forcing of parts together, here is the prototype:

 

Errata: 

-ball bearing spacing not great enough.The bearing did not fit together, I’m guessing because there wasn’t a big enough gap between the ball bearings and the two sides of the bearing.

-the upper bearing needs more depth in order to comfortably rest in place, but it just bearly works.

-the motor holders required many minutes of sanding and filing to fit the motors, but now it fits perfectly.

-the gear should probably be a miter, also there is nothing holding the sprocket down in place.

******

Took apart a bunch of small stuff to have small screws and rods:

To fix the board to the bar I used a part I found in a floppy disk drive:

 

Showing the M1.6 screws holding the top 3D print in place and some M3 black bolts to keep the inner bearing off the ground.

I wired up the two motors as well to see how that would work:

*******

Here is an attempt at making something similar from stepper motors (of course they need to be powered to hold their position so they can’t really be weight bearing). The nice thing about steppers is the mini linear threaded drives which could be added to the pan-tilt to give the machine the ability to move around shadows? 

 

3D modeling the pan tilt with two steppers:

…and one stepper / one DC gearmotor:

Here is the design worked a bit more and ready to print:

Here is how the print and assembly turned out:

 

I like how the translucent print blends with the different metal and plastic shades. For the electronics I’m planning four LRDs and a super simple program (with batt for super reactive demo?). One could either imagine a whole array of the same sun tracking devices, or a series of different families of devices mixed together in an array, which would all react in the same way to moving a light bulb into the space above the robots….

Errata:

-Everything is still a bit too snug with 0.1mm offsets. I should have made the spacing for the rail even bigger because it needs to actually slide…

-I designed using a bearing I only have one of and was already using in another machine…

-The holes for the read DC motor mounting didn’t come through.

-The top part which holds the rod and attaches to the linear rail broke because it was super weak in the middle.

-The bottom brace is not long enough to force the panel into more acute angles.

-The tension in the rubber belt is not sufficient to turn the base…

-The threaded rod nut plastic piece is not pushed sufficiently into the threaded rod to grip effectively. It needs to be closer to the rod so the built-in spring is in tension.

****************

I have some new parts: M2 bolts and nuts as well as steppers with gear reductions.

Taking apart more DVD roms I had the idea of remaking this device entirely from e-waste parts. I have six kits so far:

The idea would be to make this design:

There are about four sets of the same components available from the 8 DVD drives I took apart. I am redesigning the 3D model with these parts in mind.

There is also the possibility of using the motor drivers from the boards themselves except that they require a 12V VCC…

Here is a post describing how they could be hacked: https://electronics.stackexchange.com/questions/341519/i-need-help-controlling-the-sled-motor-of-a-cd-rom-based-off-of-a-datasheet

Image of the BD7907FS Circuit Diagram

Here are some details about this next design:

-it incorporates another found motor of the DVD rom device instead of the geared DC motor ordered from Polulu. 

-it has tracks instead of holes for sensitive spots (like the DC motor mount and the threaded rod nut) so that things can be adjusted and then bolted when they are just perfect.

-I replaced the central bearing for the correct diameter.

-I made the upper 3D printed peice more structurally sound so hopefully it won’t break this time. 

-I made larger offsets for inserts (except for the rod holders which I want to be snug) 0.2mm all around instead of 0.1mm this time. 

-I made a recessed track for the gear belt holder on the DC motor. 

-I fiddled such that the angle range for the panel is greater now. 

 

In parallel I’m working on the simplest version of a test board possible:

-super cap will need to be manually charged

-4 photodiodes for solar orientation will be manually wired to avoid challenging trace designs.

-only the most essential stuff for the motor drivers and microchip. 

The idea is that I can make a video showing the device tracking a light source in real time super “responsively”. This could then easily be modified to be the actual sun seeking circuit. 

I will have four little directional shaders which will cast shadows if the four photodiodes are not all pointed directly at the same light source. 

https://www.sciencedirect.com/science/article/abs/pii/S2213138818300080

Open hardware/software test bench for solar tracker with virtual instrumentation - ScienceDirect

I made a quick PCB then decided what I really need is an air wired arduino with motor drivers to test this.

Errata from second stepper prototype:

-The 3D printed piece that holds the leadscrew nut is too thick for my M2 bolts and so it cannot be bolted on.

-I forgot to subtract the bottom toothed part of the black gear belt wheel from the base.

-most of the offsets are too loose. 

-with the wider heavier DC motor the base is no longer stable enough.

-I forgot to subtract the flange of the DC motor (like a collar around the axle) from the bracket that it attached to.

Next I will get a quick mock up with some light sensors mounted on the four corners of the solar panel enabling an arduino to follow a light source. This won’t be embedded on a board yet, it will just be a test.

 

***********

I’m using a DRV8835 motor shield and an easy stepper motor driver for this mock up with the LDRs wired like this (but with 1Ks instead of 10Ks):

Working with Light Dependent Resistor (LDR) - Arduino Project Hub

Here is the code I’m using to control the LDR sensing sun seeker;

#include <DRV8835MotorShield.h>

#define LED_PIN 13

DRV8835MotorShield motors;

//Declare pin functions on Redboard
#define stp 2
#define dir 3
#define MS1 4
#define MS2 5

#define BPHASE 10
#define BEN 9

#define EN 6

int sensorPin1 = A0;
int sensorPin2 = A1;
int sensorPin3 = A2;
int sensorPin4 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;
int sensorValue3 = 0;
int sensorValue4 = 0;

//Declare variables for functions
char user_input;
int x;
int y;
int state;

void setup() {

Serial.begin(9600);
pinMode(sensorPin1, INPUT);
pinMode(sensorPin2, INPUT);
pinMode(sensorPin3, INPUT);
pinMode(sensorPin4, INPUT);

pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(EN, OUTPUT);
resetEDPins(); //Set step, direction, microstep and enable pins to default states

pinMode(LED_PIN, OUTPUT);

pinMode(BPHASE, OUTPUT);
pinMode(BEN, OUTPUT);
}

//Main loop
void loop() {

sensorValue1 = (analogRead(sensorPin1) + analogRead(sensorPin1) + analogRead(sensorPin1))/3;
sensorValue2 = (analogRead(sensorPin2) + analogRead(sensorPin2) + analogRead(sensorPin2))/3;

sensorValue3 = (analogRead(sensorPin3) + analogRead(sensorPin3) + analogRead(sensorPin3))/3;
sensorValue4 = (analogRead(sensorPin4) + analogRead(sensorPin4) + analogRead(sensorPin4))/3;

if(sensorValue1 > 500 && sensorValue1 > sensorValue2)
{
StepForwardDefault();
}

if(sensorValue2 > 500 && sensorValue2 > sensorValue1)
{
ReverseStepDefault();
}

if(sensorValue3 > 500 && sensorValue3 > sensorValue4)
{
forward(10);
nomove();

}

if(sensorValue4 > 500 && sensorValue4 > sensorValue3)
{
backward(10);
nomove();

}

//StepForwardDefault();
//ReverseStepDefault();

//forward(50);
//backward(50);
//nomove();

}

void forward(int t)
{

digitalWrite(BEN, HIGH); //forward
digitalWrite(BPHASE, LOW);
delay(t);

}

void backward(int t)
{

digitalWrite(BEN, HIGH); //backward
digitalWrite(BPHASE, HIGH);
delay(t);

}

void nomove()
{

digitalWrite(BEN, LOW); //no movement
digitalWrite(BPHASE, LOW);

}

//Reset Easy Driver pins to default states
void resetEDPins()
{
digitalWrite(stp, LOW);
digitalWrite(dir, LOW);
digitalWrite(MS1, LOW);
digitalWrite(MS2, LOW);
digitalWrite(EN, HIGH);
}

//Default microstep mode function
void StepForwardDefault()
{

digitalWrite(dir, LOW); //Pull direction pin low to move “forward”
for(x= 0; x<100; x++) //Loop the forward stepping enough times for motion to be visible
{
digitalWrite(stp,HIGH); //Trigger one step forward
delay(1);
digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
delay(1);
}

}

//Reverse default microstep mode function
void ReverseStepDefault()
{

digitalWrite(dir, HIGH); //Pull direction pin high to move in “reverse”
for(x= 0; x<100; x++) //Loop the stepping enough times for motion to be visible
{
digitalWrite(stp,HIGH); //Trigger one step
delay(1);
digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
delay(1);
}

}

// 1/8th microstep foward mode function
void SmallStepMode()
{

digitalWrite(dir, LOW); //Pull direction pin low to move “forward”
digitalWrite(MS1, HIGH); //Pull MS1, and MS2 high to set logic to 1/8th microstep resolution
digitalWrite(MS2, HIGH);
for(x= 0; x<1000; x++) //Loop the forward stepping enough times for motion to be visible
{
digitalWrite(stp,HIGH); //Trigger one step forward
delay(1);
digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
delay(1);
}

}

//Forward/reverse stepping function
void ForwardBackwardStep()
{

for(x= 1; x<5; x++) //Loop the forward stepping enough times for motion to be visible
{
//Read direction pin state and change it
state=digitalRead(dir);
if(state == HIGH)
{
digitalWrite(dir, LOW);
}
else if(state ==LOW)
{
digitalWrite(dir,HIGH);
}

for(y=0; y<1000; y++)
{
digitalWrite(stp,HIGH); //Trigger one step
delay(1);
digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
delay(1);
}
}

}

 

***********************

To make an on-board version of the breadboard prototype I made, I think I can reuse a previous version of this circuit which has two motor drivers and even a couple of spots for LDRs (I would just ignore the radio and sensor side of things for the moment at least):

(I may need to add a CS pull-up resistor and a 0.1uF cap to power as these were two erratta from this version of the board.) 

This turned out to be a bad idea, there are approximately 3,590 jumpers between the two boards, so no practical at all.

I am thinking of making miniature smd light sensor pairs (we have smd photodiodes in the lab) that would attach to the outside of the board on 3D printed T-shaped things:

When light is straight ahead, difference between LDRs will be minimal. Moment that one is significantly darker than the other, the motor which turns the dark side towards the light needs to come on until they are equalized again. So more of a nested if loop?

if(sensor1-sensor2 > 200){// difference in sensors

if(sensor1>100&&sensor2<50) //turn motor CW

else()//turn motor CCW

****************

Because the board already has the radio built in, I wonder if I should reincorperate it into the project. I also recieved some female SMA board antenna connectors which I could incorperate into the new version.

10Pcs SMA Female Solder Edge PCB Mount Straight RF Connector Plug ...

************

New code:

#include <Stepper.h>

// change this to the number of steps on your motor
#define STEPS 200

// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it’s
// attached to
Stepper stepper(STEPS, A2, A3, A5, A4);

#define RED 3 // RED LED

int sensorPin1 = A0;
int sensorPin2 = A1;
int sensorPin3 = A6;
int sensorPin4 = A7;
int sensorValue1 = 0;
int sensorValue2 = 0;
int sensorValue3 = 0;
int sensorValue4 = 0;

void setup()
{

pinMode(sensorPin1, INPUT);
pinMode(sensorPin2, INPUT);
pinMode(sensorPin3, INPUT);
pinMode(sensorPin4, INPUT);

pinMode(6, OUTPUT); //

pinMode(7, OUTPUT); //

// set the speed of the motor to 30 RPMs
stepper.setSpeed(60);
}

void loop()
{

digitalWrite(6, LOW); //
digitalWrite(7, LOW); //

sensorValue1 = (analogRead(sensorPin1) + analogRead(sensorPin1) + analogRead(sensorPin1))/3;
sensorValue2 = (analogRead(sensorPin2) + analogRead(sensorPin2) + analogRead(sensorPin2))/3;

sensorValue3 = (analogRead(sensorPin3) + analogRead(sensorPin3) + analogRead(sensorPin3))/3;
sensorValue4 = (analogRead(sensorPin4) + analogRead(sensorPin4) + analogRead(sensorPin4))/3;

if(sensorValue1 > 500 && sensorValue1 > sensorValue2)
{
clockwise();
delay(500);
}

if(sensorValue2 > 500 && sensorValue2 > sensorValue1)
{

counter_clockwise();
delay(500);
}

if(sensorValue3 > 500 && sensorValue3 > sensorValue4)
{
stepper.step(STEPS);

}

if(sensorValue4 > 500 && sensorValue4 > sensorValue3)
{
stepper.step(-STEPS);
}

digitalWrite(6, LOW); //
digitalWrite(7, LOW); //

}

int clockwise()
{

digitalWrite(6, HIGH); //
digitalWrite(7, LOW); //

}

int counter_clockwise()
{

digitalWrite(6, LOW); //
digitalWrite(7, HIGH); //

}

Circuit Protection + PCB Design Rules of Thumb

I just destroyed a circuit I spent over a week preparing and I decided I would learn how to better protect my circuits.

Reverse Polarity protection:

A diode can be used to protect a circuit but it will drop 0.7V and will waste power. A shotky diode will only drop .3-.4V but it has the same issue. A P-Channel MOSFET set up where the gate is connected to ground will only turn on when the polarity is correct. If Vin is not greater than the maximum allowed voltage you can put accross the MOSFET from gate to source (Vgs max.), or the Vin is not less than the threshold required for the P-FET to turn on (Vgs th), then it doesn’t need any other components.

Image result for how to protect circuits from reverse voltage polarity

For overvoltage protection (https://circuitdigest.com/electronic-circuits/overvoltage-protection-circuit):

When the voltage is below the Zener Diode’s 5.1V reverse threshold, Q2’s base is HIGH  (through the 2.2K resistor) so the PNP is off. This means that Q1 is ON (because it’s PNP base is connected to ground via 6.8K) and the circuit is powered.

When the voltage is above the Zener Diode’s 5.1V reverse threshold, Q2 is connected to ground and is turned on. This connects Q1 with VCC and therefore turns it off, disconnecting the circuit from the power. 

Overvoltage Protection Circuit Diagram

For short circuit protection:

Q2 is a PNP, Q1 is an NPN. Here is my understanding based on the site https://circuitdigest.com/electronic-circuits/short-circuit-protection-circuit-diagram

First a small amount of current reaches the base of Q1 (via R5 and the D2), causing it to turn on Q2. Now current flows through Q2 into R4 and D1 while keeping Q1 on. Current is no longer flowing through D2.

When a short occurs, current passes directly towards ground from Q2 and therefore no longer turns Q1 on. This turns off Q2 and now current passes via R5 and D2, skipping D1 and still skipping R2 towards Q1, directly to ground. Instead of having a short, we now have current passing through R5 and D2. 

Short Circuit Protection Block Diagram

PCB Design (from https://www.youtube.com/watch?time_continue=5&v=NJKZZArjdg8&feature=emb_logo):

-rounded corner for logic levels, straight corners “round edges”. (Though not everyone seems to agree on this). 45 degree angles are good, 90 are bad.

-minimize trace lengths, components electronically close should be physically close too. Longer traces have higher resistance, capacitance and inductance. 

-Think in terms of a signal chain, with input on the left moving towards output on the right. Divide things into building blocks. Build each block separately and then throw it on the main board. 

-VCC should be connected via a star-like formation to sub systems, with branches of equal length, NOT in a cascaded or serial way where the last sub system is furthest away from VCC. This will make the later sub systems vulnerable to noise produced by the upstream ones.

-Mechanical parts (pots, switches, barrel connectors) fail before electrical parts.

-watch out for your ground returns (the path that a component’s ground path with take to make it back to the power regulator). If it is zig zaggy and not short this is not ideal.

-don’t forget to add test points! 

This website helps to calculate the correct width of traces for a given current:

http://circuitcalculator.com/wordpress/2006/01/31/pcb-trace-width-calculator/

This resource looks good for more in depth: http://alternatezone.com/electronics/files/PCBDesignTutorialRevA.pdf

Here is a table showing minimum trace widths for different thicknesses of copper:

•••••••••••••••

-work in mils, most components are designed with 100 mil spacing (0.1″). 

-For your Eagle grid, had a 25 thou alt grid with a 50 thou main grid. Or a 25mil/10mil for finer work. Use a SNAP grid.

-bigger traces are better generally, they have lower DC resistance and lower inductance.

-25 thou for signal traces, 50 thou for power, 10-15 for traces going in between ICs is a good place to start. 

-oval shaped pads for ICs, circular for leaded resistors and caps. 

-minimize the number of drill bits that will be required by the board house to make your circuit.

-check that when you actually add the components, screws, etc., it all fits and doesn’t cause potential shorts. 

-do not mix analog and digital sub systems in the same circuit, nor high current or frequency and low current and frequency. 

-leave a rectangle at the top of the solder mask so you can write something in pen on the board!

-for a two sided board, the bottom can be a ground plane. You should not have the ground plane extend all the way to the edge of the board. The more copper in your ground path the lower the impedance. 

-Use multiple vias to connect the same signal to ground to lower impedance. 

-One bypass cap per IC: 10nF or 1nF for higher frequencies, and 1uF or 10uF for low frequencies

-boards are typically made with 1oz. copper thickness and are 1.6mm thick fiberglass FR4.

-don’t forget to add a signature/logo to your board!

Visualizing your circuit before building:

https://www.falstad.com/circuit/

Fab 15 Part VI

Here is my first attempt at making a video of this all working:

I would like the next version of the video to show:-starting charging from zero.-the burst of packets sent at the begining and how it finds a balance afterwards. 
 -the sky in the background so it’s easy to understand how the clouds effect the charging rate.Here is me assembling the final boards:

 

I tried to power the motors using the motor driver on the flip side, I got weird results until I unplugged the ICSP header. After that everything worked as expected except when the power supply was turned off for some reason the motor drivers stopped working.

I have a problem of not having enough pins broken out.

For the VEML7700, I downloaded the following Adafruit libraries:

https://github.com/adafruit/Adafruit_VEML7700

https://github.com/adafruit/Adafruit_BusIO

For some reason I also needed to include the SPI.h file otherwise it would not compile.

Adding the VEML7700 code somehow makes the original code no longer work… I should now try with a vanilla arduino just to make sure the test code works.

The VOUT voltage sensing appears to work. This is a nice option because it means that just by taking the integral of the VOUT we can see if the solar panel position is getting more light (i.e. no need for multiple light sensors if we’re willing to spend some energy on motors in the spirit of trail and error sensing).

I have noticed that LDO is not stable at 2.2V but dips to below 2V. I’m not sure how related this is to the power supply being connected to the LTC3105.

I am working on a new minimal iteration of the sun seeking functionality.

Here is another 3D model I’m working on. The idea is that it cannot destroy itself by accident (it can turn all the way around in both axes and not break anything). It is also independent of whatever surface it is placed on. The bearing at the center allows everything to rotate freely.

Here are some sketches of me trying to figure out how to model the rotary thing:

The resin prints were pretty disastrous… The bearing didn’t fit and neither did the motors or the central axis pin! After some filing and hot gluing things fit a bit better.

P1000330

Here is the full assembly. It’s extremely inelegant. Here are some issues:

-stiff wires.

-the weight of things…Everything is straining the central axis pin, and the main mast supporting the solar panel board is not being held straight up.

-The tilt arm is hitting the rotary gear, it needs to be smaller. 

-everything is incredibly fragile and finicky.

 

Replacing the mast with just a simple arm is less inelegant:

Of course now the machine can destroy itself by just turning into the board hits something…It also needs a better solution for the solar panel being attached to the board somehow that can be easily removed for programming. 

The main axis which fits into the bearing is still problematic. 

This beautiful object was made by Mr. Paulo Salvagione at Pier 9. This would make a better base for the rotating part of this project I think. It could be made so that it fits the motor very snugly with no play.

I’ve decided to make my life easier and to go towards a more obvious solution for the next iteration. It will at least give me a chance to see how the balance of the object behaves over the course of a day. I’ve printed this version before in PLA but never in resin.

I’m taking the offset of .1mm all around to make the motors fit snugly. 

Here is the Arduino code I have developed so far:

/*

*/

const int pgood = 3;
const int cap_voltage = A2;
const int delay_time = 100;
const int motor_time = 500;

float cap_reading_0;
float cap_reading_1;
float cap_reading_2;
float cap_reading_3;
float cap_reading_4;

float cap_reading_average;

int integral_0;
int integral_1;
int integral_2;
int integral_3;
int integral_4;

int integral_total;

int current_reading;
int last_reading;

// the setup function runs once when you press reset or power the board
void setup() {

// motor driver pins
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);

pinMode(A0, OUTPUT);
pinMode(7, OUTPUT);

pinMode(cap_voltage, INPUT); //
pinMode(pgood, INPUT); //
}

// the loop function runs over and over again forever
void loop()
{
if (pgood==HIGH)
{
evaluate_east_west();
evaluate_north_south();
}
}
int evaluate_east_west()
{
last_reading = integral();
clockwise();
delay(motor_time);
current_reading = integral();

if(last_reading>current_reading) // move back if less sun in new position
{
counter_clockwise();
delay(motor_time);
}

last_reading = integral();
counter_clockwise();
delay(motor_time);
current_reading = integral();

if(last_reading>current_reading) // move back if less sun in new position
{
clockwise();
delay(motor_time);
}
}

int evaluate_north_south()
{
last_reading = integral();
tilt_up();
delay(motor_time);
current_reading = integral();

if(last_reading>current_reading) // move back if less sun in new position
{
tilt_down();
delay(motor_time);
}

last_reading = integral();
tilt_down();
delay(motor_time);
current_reading = integral();

if(last_reading>current_reading) // move back if less sun in new position
{
tilt_up();
delay(motor_time);
}
}

int cap_voltage_read()
{
cap_reading_0 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_1 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_2 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_3 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_4 = analogRead(cap_voltage);
delay(delay_time);

return cap_reading_average = (cap_reading_0 + cap_reading_1 + cap_reading_2 + cap_reading_3 + cap_reading_4) / 5;
}

int integral()
{

integral_0 = (int)cap_voltage_read(); // convert to int
delay(delay_time);
integral_1 = (int)cap_voltage_read(); // convert to int
delay(delay_time);
integral_2 = (int)cap_voltage_read(); // convert to int
delay(delay_time);
integral_3 = (int)cap_voltage_read(); // convert to int
delay(delay_time);
integral_4 = (int)cap_voltage_read(); // convert to int
delay(delay_time);

return integral_total = integral_0 + integral_1 + integral_2 + integral_3 + integral_4;
}

int clockwise()
{
digitalWrite(A5, HIGH); //
digitalWrite(A4, LOW); //

digitalWrite(A0, LOW); //
digitalWrite(7, LOW); //
}

int counter_clockwise()
{
digitalWrite(A5, LOW); //
digitalWrite(A4, HIGH); //

digitalWrite(A0, LOW); //
digitalWrite(7, LOW); //
}

int tilt_up()
{
digitalWrite(A5, LOW); //
digitalWrite(A4, LOW); //

digitalWrite(A0, HIGH); //
digitalWrite(7, LOW); //
}

int tilt_down()
{
digitalWrite(A5, LOW); //
digitalWrite(A4, LOW); //

digitalWrite(A0, LOW); //
digitalWrite(7, HIGH); //
}

 

The current issue I’m having is with PGOOD which is for some reason hovering around 1V instead of 2.2V. When I remove the PGOOD test things appear to work.

Here is the resin print, it’s not bad! I think I will turn the top arm outwards so that no matter what happens the machine won’t destroy itself (at least during the testing phase).

And here is with the board attached:

And here is a video of the thing rotating:

P1000390

PGOOD is not working so I’m just making the code test the voltage of the capacitor when it wakes up. I’ve also added a motor_stop() function because I forgot to stop the motors turning during the time consuming voltage checking functions. This appears to work.

void loop()
{
if(((int)cap_voltage_read()) > 410)

// this is 1/3 – 20K/10K R divider of 2.7V out of a 2.2V LDO scale, mapped into 1023
{
evaluate_east_west();
evaluate_north_south();
}
}

I was noticing that there was considerable leakage from the capacitor without serious sun. I decided this was probably from having the motor driver sleep pin connected to PGOOD. I have disconnected PGOOD from the micro-controller, and now used that pin to turn on and off the motor sleep. If this doesn’t solve the problem the other candidate is the leakage from the resistor divider which could be replaced by a mosfet as per the JeeLabs zero current measuring post. This would require another pin from the microchip and a bit more space on my already crammed board…

(The next version of this board may need to be manufactured at a board house, not being able to easily make two sided boards is becoming very frustrating. I also want to use the fancy RF connectors and antennae I ordered.)

Hunting for the cause of the leaking current. The voltage seems to stabilize at 1.29V, not sure what that tells us though..

I’m using our super fancy Keithley DMM7510 7 1/2 Digit Multimeter. Check it out:

I added sleep mode to the code and now once the voltage hits 2.6V it stays essentially stable. (The motor driver uses 1.6-2.5uA @ 5V, the atmega 328p 1uA @ 3V, and the 3V/30K voltage divider draws 100uA.)

Already mentioned blog posts from Jeelabs on measuring battery voltage:

https://jeelabs.org/2013/05/15/what-if-we-want-to-know-the-battery-state/

https://jeelabs.org/2013/05/16/measuring-the-battery-without-draining-it/

https://jeelabs.org/2013/05/17/zero-powe-battery-measurement/

I’m wondering if I want to make things easier and have four mini solar panels and two comparators like this (http://www.ti.com/lit/ds/sbos589/sbos589.pdf) so that only two pins are required to determine which direction to move in. I could also possibly use the BEAM solarbotics “suspended bicore” solution (http://www.beam-online.com/Robots/Circuits/circuits.html#Phototropic%20Bicore).

There is a flaw in my system, if suddenly the sun comes out at the perfect time, the robot can think that turning away from the sun led to finding more sun whereas in fact it was just the sun that changed. I could solve this by having the robot do multiple experiments before committing to actually changing its angle. 

I should also include in the code a moment where the machine decides if the difference between the past and current reading is sufficiently great to necessitate moving. 

I have another problem. There is some give in the gearmotors, therefore they do not turn the same amount when they switch directions. This is bad but it’s critical when combined with the code not working very well. This is more an issue for the tilt motor, so if I could replace this with an earlier design rotating a metal rod and using a mast to take the weight of the board perhaps that would solve my problem. 

I’m hoping I wouldn’t need these: https://www.pololu.com/product/4761…

Just realized my code is not doing what I want it to do. The integral() function is absolute, it is adding bigger and bigger numbers instead of looking at the difference between relative values…Fixed this. 

I find the machine spends a lot of time moving back and forth between the same positions. It is rarely deciding that a new orientation is better than an old. I should get the radio set up so I can see the values that are being sent.

I also need to replace the tilt mechanism with one that holds the weight of the board like the mast/rotation system I tried earlier. I should also do east/west rotation before moving on to doing both axes at once.

Did a quick test, analogRead() has 10 bit resolution, giving a value between 0-1023. The resolution is barely good enough for taking a reading every 10 seconds and seeing a dropping voltage value in the cap. I think I should be taking measurements every few minutes to be able to detect a difference in charging. 

I think I need to turn the radio off for long delays, otherwise it doesn’t work. I’m trying radio.sleep(). 

I also realized it would make far more sense to sense the solar panel voltage rather than the capacitor voltage to sense the solar aspect. However this would add another input pin…

*I think I might need to update the below code to include the floor() function which stops arduino from rounding? https://www.nongnu.org/avr-libc/user-manual/group__avr__math.html#ga0f0bf9ac2651b80846a9d9d89bd4cb85

Here is the far from optimal code so far:

// Include the RFM69 and SPI libraries:
#include <SPI.h>
#include <avr/wdt.h>
#include <RFM69.h>
#include <avr/sleep.h>
#include “LowPower.h”

// Addresses for this node. CHANGE THESE FOR EACH NODE!

#define NETWORKID 0 // Must be the same for all nodes
#define MYNODEID 2 // My node ID
#define TONODEID 1 // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:

//#define FREQUENCY RF69_433MHZ
#define FREQUENCY RF69_915MHZ

// AES encryption (or not):

#define ENCRYPTKEY “TOPSECRETPASSWRD” // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):

#define USEACK true // Request ACKs or not

// Packet sent/received indicator LED (optional):

#define LED A3 // LED positive pin

#define PGOOD 3 // PGOOD

#define MOSFET 9//

// Create a library object for our RFM69HCW module:

const int cap_voltage = A2;
const int delay_time = 100; //30 x delay_time (?) is how long it takes to take an integral of cap voltage
const int long_delay_time = 7000; //30 x delay_time (?) is how long it takes to take an integral of cap voltage

double T;

const int motor_sleep = 3;
const int motor_time = 200;

int current_reading;
int last_reading;

RFM69 radio;

void setup()
{
// Open a serial port so we can send keystrokes to the module:

pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);
pinMode(MOSFET,OUTPUT); //mosfet
// pinMode(PGOOD, INPUT); // PGOOD

// motor driver pins
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);

pinMode(A0, OUTPUT);
pinMode(7, OUTPUT);

pinMode(motor_sleep, OUTPUT);
pinMode(cap_voltage, INPUT); //

}

void loop()
{

wdt_enable(WDTO_8S);

digitalWrite(MOSFET, LOW); // turn off MOSFET

if(((int)cap_voltage_read()) > 410)
{
digitalWrite(motor_sleep, LOW); // sleep motor driver
Radio_Send(); //includes init and mosfet turn on
digitalWrite(MOSFET, LOW); // turn off radio

T = integral();

Radio_Send();
digitalWrite(MOSFET, LOW); // turn off MOSFET
evaluate_east_west();
}
else
{
digitalWrite(motor_sleep, LOW); // sleep motor driver
digitalWrite(MOSFET, LOW); // turn off MOSFET
sleep(); // sleep microchip
}
}

int evaluate_east_west()
{
last_reading = integral();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
motors_off(); //also sleeps driver
wait_long();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
clockwise();
delay(motor_time);
motors_off();
current_reading = integral();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset

if(last_reading>=current_reading) // move back if less sun in new position
{
counter_clockwise();
delay(motor_time);
motors_off();
}
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset

wait_long();

last_reading = integral();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
counter_clockwise();
delay(motor_time);
motors_off();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
delay(long_delay_time);
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
current_reading = integral();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset

if(last_reading>=current_reading) // move back if less sun in new position
{
clockwise();
delay(motor_time);
motors_off();
}
digitalWrite(motor_sleep, LOW);
}

int Radio_Send()
{
char Tstr[10];

digitalWrite(MOSFET, HIGH); // turn on MOSFET
delay(100);
radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
radio.setHighPower(); // Always use this for RFM69HCW

// Turn on encryption if desired:

radio.encrypt(ENCRYPTKEY);

char buffer[50];

dtostrf(T, 5,5, Tstr);

static int sendlength = strlen(buffer);

sprintf(buffer, ” T:%s”, Tstr);

radio.sendWithRetry(TONODEID, buffer, sendlength);

Blink(LED,100);

}

int integral()
{
int integral_0;
int integral_1;

//int integral_total;

int integral_total_1;

integral_0 = (int)cap_voltage_read(); // convert to int
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
wait_long();
wait_long();
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
integral_1 = (int)cap_voltage_read(); // convert to int
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset

integral_total_1 = integral_1 – integral_0;

return integral_total_1;
}

int cap_voltage_read()
{
float cap_reading_0;
float cap_reading_1;
float cap_reading_2;
float cap_reading_3;
float cap_reading_4;

float cap_reading_average;

cap_reading_0 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_1 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_2 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_3 = analogRead(cap_voltage);
delay(delay_time);
cap_reading_4 = analogRead(cap_voltage);
delay(delay_time);

return cap_reading_average = (cap_reading_0 + cap_reading_1 + cap_reading_2 + cap_reading_3 + cap_reading_4) / 5;
}

void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}

void sleep(void)
{
digitalWrite(MOSFET, LOW); // turn on MOSFET
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //select PWR DOWN, the most power savings
sleep_enable(); //set SE bit
sei(); // enable global interrupts
sleep_cpu(); //actually sleep
sleep_disable(); //code reaches this point after interrupt
}

int motors_off()
{
digitalWrite(motor_sleep, LOW); //put driver to sleep
digitalWrite(A5, LOW); //
digitalWrite(A4, LOW); //

digitalWrite(A0, LOW); //
digitalWrite(7, LOW); //
}

int clockwise()
{
digitalWrite(motor_sleep, HIGH); //wake up driver
digitalWrite(A5, HIGH); //
digitalWrite(A4, LOW); //

digitalWrite(A0, LOW); //
digitalWrite(7, LOW); //
}

int counter_clockwise()
{
digitalWrite(motor_sleep, HIGH); //wake up driver
digitalWrite(A5, LOW); //
digitalWrite(A4, HIGH); //

digitalWrite(A0, LOW); //
digitalWrite(7, LOW); //
}

int tilt_up()
{
digitalWrite(motor_sleep, HIGH); //wake up driver
digitalWrite(A5, LOW); //
digitalWrite(A4, LOW); //

digitalWrite(A0, HIGH); //
digitalWrite(7, LOW); //
}

int tilt_down()
{
digitalWrite(motor_sleep, HIGH); //wake up driver
digitalWrite(A5, LOW); //
digitalWrite(A4, LOW); //

digitalWrite(A0, LOW); //
digitalWrite(7, HIGH); //
}

int wait_long()
{

for(int i=0;i<10;i++)
{
wdt_reset(); // do this before 8 seconds has elapsed so we don’t reset
digitalWrite(motor_sleep, LOW); //put driver to sleep
digitalWrite(MOSFET, LOW); // turn off radio MOSFET
LowPower.idle(SLEEP_4S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
SPI_OFF, USART0_OFF, TWI_OFF);
}

}

DIY Mini Drone

For a change, this is a video of me working on the boards for this project:

 

 

Radios are working, I’m struggling with the best way to poll the joysticks. I think I need to use Pin Change Interrupts (Interrupts for pins other than those dedicated for interrupting). The other option is just to have polling:

if (UP == HIGH){ Send(UP);}

if (DOWN == HIGH){ Send(DOWN);}

etc.

*Later realized that I messed this up, what I want is to check if the pin is LOW (i.e. if it is connected to ground and not internally pulled up) and then have an else at the end which turns to HIGH.

*I forgot to put pull-up resistors on the actual board so I used the avr’s internal ones. In arduino you do this like so:

pinMode(A0, INPUT_PULLUP);

I reprinted the drone frame with .1mm extra space around the circle and now the motors fit snuggly. 

Dissapointed that the joysticks only register an up or down when also pushed down…

Here is the joystick sending code:

********************************************************************************

// RFM69HCW Example Sketch
// Send serial input characters from one RFM69 node to another
// Based on RFM69 library sample code by Felix Rusu
// http://LowPowerLab.com/contact
// Modified for RFM69HCW by Mike Grusin, 4/16

// This sketch will show you the basics of using an
// RFM69HCW radio module. SparkFun’s part numbers are:
// 915MHz: https://www.sparkfun.com/products/12775
// 434MHz: https://www.sparkfun.com/products/12823

// See the hook-up guide for wiring instructions:
// https://learn.sparkfun.com/tutorials/rfm69hcw-hookup-guide

// Uses the RFM69 library by Felix Rusu, LowPowerLab.com
// Original library: https://www.github.com/lowpowerlab/rfm69
// SparkFun repository: https://github.com/sparkfun/RFM69HCW_Breakout

// Include the RFM69 and SPI libraries:

#include <RFM69.h>
#include <SPI.h>

// Addresses for this node. CHANGE THESE FOR EACH NODE!

#define NETWORKID 0 // Must be the same for all nodes (0 to 255)
#define MYNODEID 1 // My node ID (0 to 255)
#define TONODEID 2 // Destination node ID (0 to 254, 255 = broadcast)

// RFM69 frequency, uncomment the frequency of your module:

//#define FREQUENCY RF69_433MHZ
#define FREQUENCY RF69_915MHZ

// AES encryption (or not):

#define ENCRYPT true // Set to “true” to use encryption
#define ENCRYPTKEY “TOPSECRETPASSWRD” // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):

#define USEACK true // Request ACKs or not

// joystick and leds

#define LED1 A0 // LED positive pin
#define UP1 A2//
#define LEFT1 A3//
#define RIGHT1 A4//
#define DOWN1 A5//

#define LED2 A1 // LED positive pin
#define UP2 8//
#define LEFT2 9//
#define RIGHT2 7//
#define DOWN2 6//

// Create a library object for our RFM69HCW module:
RFM69 radio;

void setup()
{
// leds and joystick init

pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);

pinMode(UP1,INPUT_PULLUP);
pinMode(LEFT1,INPUT_PULLUP);
pinMode(RIGHT1,INPUT_PULLUP);
pinMode(DOWN1,INPUT_PULLUP);

pinMode(UP2,INPUT_PULLUP);
pinMode(LEFT2,INPUT_PULLUP);
pinMode(RIGHT2,INPUT_PULLUP);
pinMode(DOWN2,INPUT_PULLUP);

// Initialize the RFM69HCW:

radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
radio.setHighPower(); // Always use this for RFM69HCW

// Turn on encryption if desired:

if (ENCRYPT)
radio.encrypt(ENCRYPTKEY);
}

void loop()
{
//setting up variables for button states

int sensorVal0 = digitalRead(UP1);
int sensorVal1 = digitalRead(LEFT1);
int sensorVal2 = digitalRead(RIGHT1);
int sensorVal3 = digitalRead(DOWN1);
int sensorVal4 = digitalRead(UP2);
int sensorVal5 = digitalRead(LEFT2);
int sensorVal6 = digitalRead(RIGHT2);
int sensorVal7 = digitalRead(DOWN2);

// SENDING

// In this section, we’ll gather serial characters and
// send them to the other node if we (1) get a carriage return,
// or (2) the buffer is full (61 characters).

// If there is any serial input, add it to the buffer:

char buffer[5] = “z”;

//BUTTON READING AND SENDING

if (sensorVal0 == LOW) {
buffer[0] = ‘a’;
digitalWrite(LED2, HIGH);
}

else if (sensorVal1 == LOW) {
buffer[0] = ‘b’;
digitalWrite(LED2, HIGH);
}

else if (sensorVal2 == LOW) {
buffer[0] = ‘c’;
digitalWrite(LED2, HIGH);
}

else if (sensorVal3 == LOW) {
buffer[0] = ‘d’;
digitalWrite(LED2, HIGH);
}

else if (sensorVal4 == LOW) {
buffer[0] = ‘e’;
digitalWrite(LED1, HIGH);
}

else if (sensorVal5 == LOW) {
buffer[0] = ‘f’;
digitalWrite(LED1, HIGH);
}

else if (sensorVal6 == LOW) {
buffer[0] = ‘g’;
digitalWrite(LED1, HIGH);
}

else if (sensorVal7 == LOW) {
buffer[0] = ‘h’;
digitalWrite(LED1, HIGH);
}

else {
buffer[0] = ‘z’;
digitalWrite(LED2, LOW);
digitalWrite(LED1, LOW);
}

// END OF BUTTON STUFF

if(buffer[0]!=’z’)
{

static int sendlength = 3;

radio.sendWithRetry(TONODEID, buffer, sendlength);
}

}

********************************************************************************

 

And here is the receiver code:

 

*********************************************************************************

// RFM69HCW Example Sketch
// Send serial input characters from one RFM69 node to another
// Based on RFM69 library sample code by Felix Rusu
// http://LowPowerLab.com/contact
// Modified for RFM69HCW by Mike Grusin, 4/16

// This sketch will show you the basics of using an
// RFM69HCW radio module. SparkFun’s part numbers are:
// 915MHz: https://www.sparkfun.com/products/12775
// 434MHz: https://www.sparkfun.com/products/12823

// See the hook-up guide for wiring instructions:
// https://learn.sparkfun.com/tutorials/rfm69hcw-hookup-guide

// Uses the RFM69 library by Felix Rusu, LowPowerLab.com
// Original library: https://www.github.com/lowpowerlab/rfm69
// SparkFun repository: https://github.com/sparkfun/RFM69HCW_Breakout

// Include the RFM69 and SPI libraries:

#include <SPI.h>
#include <RFM69.h>

// Addresses for this node. CHANGE THESE FOR EACH NODE!

#define NETWORKID 0 // Must be the same for all nodes
#define MYNODEID 2 // My node ID
#define TONODEID 1 // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:

//#define FREQUENCY RF69_433MHZ
#define FREQUENCY RF69_915MHZ

// AES encryption (or not):

#define ENCRYPT true // Set to “true” to use encryption
#define ENCRYPTKEY “TOPSECRETPASSWRD” // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):

#define USEACK true // Request ACKs or not

// Packet sent/received indicator LED (optional):

#define LED 1 // LED positive pin

// Create a library object for our RFM69HCW module:

RFM69 radio;

void setup()
{
// Open a serial port so we can send keystrokes to the module:

pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);

radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
radio.setHighPower(); // Always use this for RFM69HCW

if (ENCRYPT)
radio.encrypt(ENCRYPTKEY);

}

void loop()
{

// RECEIVING

// In this section, we’ll check with the RFM69HCW to see
// if it has received any packets:

if (radio.receiveDone()) // Got one!
{
// Print out the information:

// The actual message is contained in the DATA array,
// and is DATALEN bytes in size:

// char message = radio.DATA[0];

// RSSI is the “Receive Signal Strength Indicator”,
// smaller numbers mean higher power.

// Send an ACK if requested.
// (You don’t need this code if you’re not using ACKs.)

if (radio.ACKRequested())
{
radio.sendACK();
}
Blink(LED,10);
}

}

void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}

*********************************************************************************

 

Now just waiting for some new pager motors to arrive…

I’ve got some old drones which I have taken apart for batteries, motors and propellers. The motors are slightly larger to I have redesigned the 3D print. The motors are 8.5mm in diameter and I found that subtracting with an 8.8mm cylinder make for the snuggest fit.

Binary Visualizing

Using the tool bin vis, which simply assigns a shade of grey for each byte in a file, it’s possible to represent the structure of pieces of a file. Check it out, these are found 3D files from various software programs:

 

Found a cool surprise when I uploaded a .BMP file, the bytes map almost perfectly onto the image;

I want to try other uncompressed formats like RAW. Loading PNGs and JPEGs are uninteresting so far, they are just noise.

I have tried some experiments processing this data. These stem from the observation that changing the width of the viewing window, which causes the binary data to wrap around the screen, changes the representation of the data dramatically. 

In this experiment I tried to adjust the window of the binary visualizing screen to get the data to make columns, to the extend that this was possible. Some of this info must repeat at a point in the middle of a byte and therefore not map onto a grid of pixels perfectly (?).

Here is an attempt to isolate just the modules which repeat in the above image and to display only them;

I am imagining a program which goes through the file and figures out the proper width for each chunk of data so that this process can be automated. 

Some experiments I would like to try:

-what does the same form look like (say, a sphere) in different software formats?

-is it possible to identify which part of the binary file links up with which part of the 3D file? Could you isolate the repeating element and figure out exactly what it’s composed of?

-what are the similarities and differences between different 3D objects saved by the same software? (I.e. what is the software grain?)

-what do the Rhino.exe, Adobe Illustrator.exe and Revit.exe files look like?

-show a before and after compression image.

-somehow look at a program’s operation by examining it’s buffer memory live somehow?

and here’s the view of just the pixels in the same file just changing the window width:

Essentially each eight bits (eg. 01101001) are transformed into a pixel with a value of grey between black (0) and white (255):

I just visited the Glasgow Botanical Garden and watched the film Aquarela. Both experiences reminded me about the diversity of patterns and permutation of simple rules at play in the cosmos.

Image result for aquarela film"Image result for aquarela film"

Aquerela (2019) Screenshot

Image result for botanical garden glasgow"

Glasgow botanical gardens (image from http://martinbrookes.blogspot.com/2018/06/the-botanical-gardens-glasgow.html)

 

Looking at a Rhino file in a text editor you get that same “grain” feel as with bin vis:

this is from https://developer.rhino3d.com/api/RhinoCommon/html/N_Rhino_FileIO.htm

but there is also: https://developer.rhino3d.com/guides/#opennurbs

It would seem a lot easier to start with a file format that is ASCII encoded though…

This is a RAW file opened in binview, it has several images contained in it, one for each color channel I guess:

 

Here is a Bitmap file saved with interleave:

An IGS file format, ASCII readable, visualized. Pretty boring unfortunately.

I found a head inside an example Rhino file :D!

Some tests with a single image saved in different formats:

 

Sphere test:

Cube test:

Zooming in to some patterns:

Some patterns I found in 3D files (would be cool to compare to image file observations!):

With red to help identify the patterns:

For comparison here are some samples from image files:

Comparing an all white vs. all black file:

Next experiment is to copy and paste pieces of one file into others. Possibly from a compressed file into a raw file! (Wait – why?)

Insight into what we’re seeing in these files: http://www.rumint.org/gregconti/publications/taxonomy-bh.pdf

when things line up into a structure, data is fixed length. When things don’t line up we get variable length data chunks. Repeating values seem to help align data regions. Nois is encrypted in some way typically which has scrambled the structure. 

*****

The problem with this visualization is that it does not represent TIME, like my other ones. It would be cool to stretch and compress these images based on the speed with which the files were written somehow. 

**************

Update: This software called HeapMemory (https://www.nirsoft.net/utils/heap_memory_view.html) allows you to see memory created by active programs. You can output the data and then visualize it with binvis. If you did this regularly while you worked on a 3D model, you could have a representation of the file you’re working on through the eyes of the computer program. 

Here is a gif of a rhino operation and the change in the 3dm file:

and here’s a timelapse of a rhino file with transformations taking place:

UPSI Lecture Prep

 

To “present my projects or any other insights on digital fabrication, education and architecture.” The context; “The class is the second part of an intensive course on 3d modelling and CNC milling to make an 1:1 architectural structure based on simple modules.”

Here are some questions I could respond to: What are the seams, the gaps, and the moments of translation, between various subsystems in our contemporary digital design workflow?
How has software engineering culture given form to our software?
How does the computer internally represent our work – how does it “see” our design files and “understand” our design work?
Does software have a “grain”, just like wood and other materials? What is the ontology of Revit and what is the world according to Rhino 3D, for instance?
Do technological artifacts, and the objects that designers make, have innate force in themselves, as Bruno Latour and Jane Bennett seem to suggest?

I am planning a revised lecture from my UdK workshop. I would also like to present some new research but my compression research is not leading to a tangible visualization yet, I need to ask for help from programmers to accelerate this process perhaps. The other solution appears to be to go towards simpler technology from further back in history. This has the added bonus of me not working on visualizing something that a million other people are already working on as with image compression visualization. Taking a look at my map of gaps diagram…

I would like to make a GIF of the Revit startup elements. I also want to incorporate Schlossman lecture material like the number of software programs that used to exist that have all been eaten by Autodesk:

OMG here is the mother lode for all things memory visualization, this is incredibly impressive: https://reverseengineering.stackexchange.com/questions/6003/visualizing-elf-binaries

downloaded bin vis from this link, it has an .exe in the debug file: http://www.rumint.org/gregconti/publications/binviz_0.zip

I could use the techniques from the following video to compare Rhino to Revit live, or look at types of files that architects use. At the very least I could make a nice slide showing the “grain” of these different programs! I could also make the argument that because computers are so much faster than us, they can see more data at a time than we can and therefore it looks to them like watching an image (I could get the speed of their reading to equal the number of pixels we can see at a given time). 

Here is a lecture which outlines the method of mapping binary to pixel shades and how you can begin to identify species of data: https://www.youtube.com/watch?v=h68VS7lsNfE

keywords:

memory map, visual reverse engineering

https://reverseengineering.stackexchange.com/questions/6003/visualizing-elf-binaries:

word document:

Windows PE visualization

Documents Format Files

enter image description here

enter image description here

pdf:

http://actinid.org/vix/

http://binvis.io/

…I could look at things like scanners, or floppy disks?

 

In the illustration above, you can see how the disk is divided into tracks (brown) and sectors (yellow).

Floppy Disks are divided into tracks. 

Image result for kryoflux"

Nice images on how floppy disks can be damaged and the effect it has on the data https://goughlui.com/2013/04/21/project-kryoflux-part-3-recovery-in-practise/

magnetic field

speed variation

From https://link.springer.com/referenceworkentry/10.1007%2F0-387-23483-7_95 :

Data remanance:

  • Write heads used on exchangeable media (e.g., floppy disks, magstripe cards) differ slightly in position and width due to manufacturing tolerances. As a result, one writer might not overwrite the entire area on a medium that had previously been written to by a different device. Normal read heads will only give access to the most recently written data, but special high-resolution read techniques (e.g., magnetic-force microscopy) can give access to older data that remains visible near the track edges.

  • Even with a perfectly positioned write head, the hysteresis properties of ferromagnetic media can result in a weak form of previous data to remain recognizable in overwritten areas. This allows the partial recovery of..

Data is not written linearly ( 😛 ) but interleaved https://en.wikipedia.org/wiki/Interleaving_(disk_storage):

Information is commonly stored on disk storage in very small pieces referred to as sectors or blocks. These are arranged in concentric rings referred to as tracks across the surface of each disk. While it may seem easiest to order these blocks in direct serial order in each track, such as 1 2 3 4 5 6 7 8 9, for early computing devices this ordering was not practical.

[…]

To correct for the processing delays, the ideal interleave for this system would be 1:4, ordering the sectors like this: 1 8 6 4 2 9 7 5 3. It reads sector 1, processes for three sectors whereby 8 6 and 4 pass by, and just as the computer becomes ready again, sector two is arriving just as it is needed.

From the Scanning world:

scanners can interpolate pixels between scanned pixels and assume their value. This is done in software but also on chip.

Here are the proposed changes to the UdK presentation and my stock clickspace project presentation:

  1. I think I will first present my work, then talk a little about the materiality and social dimensions of technology afterwards. 

Since doing this workshop Hannah Perner-Wilson connected me with this article by Tim Ingold: https://journal.culanth.org/index.php/ca/article/view/ca30.4.03/200

I forgot to mention the materiality of how electricity is produced (by either wresting with the energy within matter itself, or burning compressed dinosaurs). Very interesting point about how electricity in modern industrial society becomes a controlling apparatus, closing itself off from people who become consumers sheltered from the actual infrastructure of electricity. When we use electricity we’re participating in a woven super structure which can help us move away from the concept of the object.

I should investigate more the Anthropocene, thunder and the electric chair along with the references in this article.

Second article The Textility of Making by Tim ingold he writes: “I want to argue that what Klee said of art is true of skilled practice in general, namely that it is a question not of imposing preconceived forms on inert matter but of intervening in the fields of force and currents of material wherein forms are generated. Practitioners, I contend, are wanderers, wayfarers, whose skill lies in their ability to find the grain of the world’s becoming and to follow its course while bending it to their evolving purpose”.

This seems to fit with the harnessing of electricity and, based on an understanding of it’s movement through various media and in various situations, co-creating something that works with this “grain”. It seems important to note that modern software has a “grain” too.

Since this workshop I have also became more interested in Legacy code (and if it could be possible to look at the varying ages of code in a big program somehow), code that needs to be ported or refactored from old code paradigmes into new ones. https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052. So far what’s interesting here is the language used to describe “code rot”. Here are some samples: “the phrase strikes disgust in the hearts of programmers. It conjured images of slogging through a murky swamp of tangled undergrowth with leaches beneath and stinging flies above. It conjures odors of murk, slime, stagnancy and offal…tangled, opaque, convoluted system…” referred to collectively as “rot”. 

Wikipedia talks about the Big Ball of Mud: A big ball of mud is a software system that lacks a perceivable architecture. Although undesirable from a software engineering point of view, such systems are common in practice due to business pressures, developer turnover and code entropy.  

They link to Brian Foote’s article:

A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated.

The overall structure of the system may never have been well defined.

If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires. Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems.

— Brian Foote and Joseph Yoder, Big Ball of Mud. Fourth Conference on Patterns Languages of Programs (PLoP ’97/EuroPLoP ’97) Monticello, Illinois, September 1997

I can improve this presentation by having more knowledge about the slides presented (such as the comparison between the two different factories, slicon disk defects, the frequency in different parts of the world). 

 

Image result for japan electricity grid"

 

This is a fascinating new practice called obfuscation where you make a product hard to reverse engineer by hiding its behavior:

Image result for hardware obfuscation circuit"

Software obfuscation:

Image result for software obfuscation"

The silicon lottery involves binning. When you overclock your chips some will max out at 4.3GHZ while others will at 5GHz. They will also require different amounts of power to achieve this. 

The reasons for the difference in the two plants: The San Diego plant emphasized zero defects while Sony of Tokyo, working with a robust quality viewpoint, strove to hit the target value for color density. I can also talk about variations in what is referred to as noise, 1. conditions of use noise (too cold, too hot, wrong voltage, too humid too dry), 2. production variation like of the two factories, 3. wear and deterioration. All these effect idiosyncrasy of products. 

Silicon impurities derive from the crystal growth process if microscopic growth is not uniform it can result in striations. Next, impurities in the silicon (carbon, boron, oxygen, nitrogen). Next, it must be annealed and then lithographically transformed. More info: https://www2.irb.hr/korisnici/icapan/paper.pdf

I also want to add that data rots, and that machines become obsolete so the digital is incredibly material.

Contactless Current Meter (IN PROGRESS)

In line with a series of low-power and energy harvesting devices I would like to make a simple Current Meter which can display the amount of energy being consumed by a given machine in our lab. I imagine the unit as a standalone thing which would use the power it harvests to power itself if possible. 

From https://www.sparkfun.com/products/11005:

Non-Invasive Current Sensor - 30A

The main issue is that this method requires a special power cord which can be split in two like so:

Image result for diy non-invasive current meter"

Using this device to monitor energy  is documented here: https://learn.openenergymonitor.org/electricity-monitoring/ct-sensors/introduction

Ordering this product from the U.S. is not easy at the moment and requires filling in some paper work. It’s also difficult to find european power wires that can be separated into two strands.

hand-powered flashlight (IN PROGRESS)

As part of a series of low-power and power harvesting devices (such as https://steemit.com/technology/@proteus-h/my-diy-passive-mini-radio-microwave-detector), I would like to make a hand-crankable or shakeable torch. I like these projects because they are not too complex, and they demonstrate very tangibly the energy that can be harvested in the environment.

from https://www.kjmagnetics.com/blog.asp?p=shake-flashlight:

 

A Servo makes a nice gear reduction (from https://www.youtube.com/watch?v=9dIkxQ_1H1k):

…and a mini version inside a tic-tac container:

Image result for shake powered flashlight

And a relay coil with a magnet makes a super tiny generator (from https://hackaday.com/2014/01/13/a-simple-led-flashlight-composed-of-a-relay-and-a-magnet/):

I’m curious to try this circuit with the solar engine voltage trigger circuit…Or to make it into another business card version.

Design Primer – Presentation for Digital Fabrication class at UP-Sud December 2019

 

This presentation serves to introduce non-designers to the culture of design. It proposes that design is like a trip, one that should take the designer outside of the “diameter of the obvious” (everything that can be imagined on day 1 and constitutes low-hanging fruit or cliche), to an unexpected place. Every design journey is unique, and this is how it should be – formulaic design is to be avoided at all costs.

The starting place of a design project is some kind of research. This could be in the form of a trip to the museum, an old book of science experiments, a thought experiment, or a found object. Research provides the material against which you push to move in some direction away from your starting place. Because design is new to academia, we usually end up borrowing ideas and data from neighboring disciplines. Research is a time when you should avoid looking at work from other designers, this is research that has already been digested in some sort. We’re looking for primary research at this stage.  (Here I could add something about the perspective you have gained from your new position on your original position – this is art!)

Design involves regular check-ins with your mentors. It’s best to have lots of objects and drawings on your desk for these moments. Many great inventions were discovered by accident (corn flakes, safety glass, the slinky, silly putty, post-it notes, etc.), and having things on your desk allows for misunderstandings and serendipitous associations.

Constraints are a key part of design. Face with a blank canvas, a rule of some kind can provide something tangible to work with. Minimilist works which test out the parameters of a single constraint and curate the results in a series are an example of one design approach. Examples are Sophie Calle’s Chromatic Regime, Sol Lewitt’s variations on open cubes, George Perec’s La Disparition, and Eadweard Muybridge’s Motion Studies. (I should know more about the examples I am bringing up to speak to them with more depth).

Constraints can be self-imposed or can be adopted from a situation. Once the work is prepared for a final presentation, the constraints can be removed like scaffolding from a building or they can be presented to the audience.

Getting stuck in a design process is natural. Brian Eno’s Oblique Strategies, a set of lateral thinking prompts, is a way to inject a foreign thought into your mind at one of these moments which may help you unblock your progress and see things from a different perspective.

Things I would like to add to this presentation:

Representation: How to describe your project? The power of collage and Scale models/scale model photography. One simple, clear idea. Do my images help describe this idea? Start at a large scale then increase when ready. Design your presentation.

Ambiguity being a tool to wield by the designer. The spectacle of the final presentation.

On research, sometimes what is most interesting is isolating a single metric, peeling away lots of data to highlight one metric. (Mauricio taught me this).

On not being precious with your creations: not allowed to destroy what you make, or edit what you make afterwards. Make tons of stuff but don’t identify with what you are making.

More on constraints: Like scaffolding, they can be removed before showing the project. Or, they can become part of the project and be presented at the end. Constraints can either be self-imposed or adopted.

I want to also introduce the concept of sketching, then moving to big scaled all the way to fine scale in the process of the design.

Talk about specificity being your friend (versus making something that does everything). Think about the thing in different situations, different seasons, many peoples, few people, etc.

The side of art/design being about you and how well you know yourself to a certain degree. The fact that this activity is more than a job but a kind of lifestyle. Self-knowledge, maturity…

Synthesizer

 

Karl and I are planning to work on other sides of the ocean on this project together. Karl will continue working on the overall collection and interaction of the modules, I’ll work on prototyping one module at a time. We hope to find a collection of modules that are cool and to see which modules we can make ourselves easily and which we need to buy chips for (such as delay).

The plan is to converge on a prototype with Karl in simulation and me in prototyping. I can mail prototypes for Karl to try in Vancouver and once we have a basic prototype we can move on to test different interfaces, and begin to think about the kit and the cost of the machine. We’re aiming currently for an intermediate level device.

We want to document things well and possibly even produce a collection of music from this device made by Karl’s artist friends. Our collaboration accross the ocean could be a theme in a video we make of the project, for instance.

*******

I am colaborating with Karl Fousek, https://karlfousek.com/, a fantastic Vancouver based sound artist. He proposed the following synth prototype:

Breaking this design up into smaller bits, I have the following designs. They are inspired also by the tinybits modular synth design found here: http://d2q6sbo7w75ef4.cloudfront.net/SYNTH-booklet.pdf

 

*****************

NOISE GENERATION

I tried this but it didn’t work with my 3.3V zener…

 

No dice either! Two more simplish options:

Simple White Noise Generator - EEWeb

Basic discrete white noise generator schematic

I could just generate noise with a microchip: https://forum.arduino.cc/index.php?topic=617302.0

I put this through a high pass filter and here are the results:

This is what the signal looks like before being put through the filter:

****

We have noise! I built the circuit from this site: http://freenrg.info/Physics/Scalar_Vector_Pot_And_Rick_Andersen/Rick_Andersen_Noisegen.htm

I used a 1M trim pot in place of the 470K to tune the noise and used 0.1uF caps in place of 0.047uF, PN2222As in place of 3904, and a 3.9K instead of a 4.7K:

Here’s what is sounds like:

 

************************

 

~~~~~~~~~~~~~~~~~

 

Sample and hold:

https://www.ti.com/product/LF398-N

Which is the circuit below (minus the comparator, I’m using Arduino to generate a pulse every 1ms of 1ms duration):

I’m using two MCP6241 op amps (I tried 741s but they don’t go rail to rail which I think was the issue) powered with 5V. I kind of arbitrarily picked 0.1uF as the C. I’m using an IRF 740. The signal generator is outputing a sine wave with 2V amplitute and a 1V offset.

Here are more screep caps :

With a triangle wave:

 

With noise:

Again with a sine:

 

XOR:

Using an 74LS86 with an arduino generated square wave every millisecond and a sine wave from the function generator, fun and easy!

PART I: OSCILLATOR

Checking to make sure everything works on breadboard first!

Synth on the oscilloscope:

 

I have taken the Atari Punk Console design and made it quickly in Eagle:

This design had two main flaws:

  1. The ground plane was too close to the signal traces, making soldering through hole components very challenging. The moment the soldering iron touches the ground plane it takes all the heat away from the iron and makes it hard to melt the solder.

2. The 3.5mm audio output jack connection was not done properly.

Also: I have also changed to two potentiometers of a different kind.

Here is rev.2:

  

And here is the final product:  

 

Errata:

I still forgot to make a dignified place for a 9V power connection…Oh well.

 

I would like to make a business card version of this circuit, seeing as we have SMD 555 and 556 in the lab!

Here is a first attempt:

 

This synth does not currently work. I think it is the replacement of the 1M pots with 50K pots. I am looking at other 556 circuits which don’t require 1M pots (which are hard to find it would seem). 

This is from the Spark Punk kit: https://core-electronics.com.au/sparkpunk-sound-kit.html

I started with this circuit then added the other modules in the spark punk kit (except the power and amplication parts).

For the frequency dividing I used a JK flip flop 74107 instead of a D-type CD4013 and set it up like so:

Image result for jk flip flop frequency divider"

I also eliminated the switches in the mixer portion (all the outputs are mixed together all the time) and used an LM386 op amp instead of the LM358.

Here is what the circuit looks like set up:

And here is what it sounds like:

Here is the PCB version before populating:

This is from Forrest Mim’s Engineer’s Mini Notebook Stepped-Tone Generator, except I don’t have any 500K pots either…

Here is a diagram that helped me understand how the 555 works:

555 Timer IC How It Works

I am now making a PCB version of the sparkpunk design. Here is the schematic (mostly copied from https://cdn.sparkfun.com/datasheets/Kits/sparkpunk-v13.pdf but with changes for the parts I have and simplified for my situation):

Meanwhile Karl has made a Max 8 patch for me to check out which varies oscillation, filter pass band and resonance (I’m thinking that this means using an inductor to make a filter):

Some important other modules:

noise + sample and hold (check the Art of Electronics)

an envelope generator (allows control of Attack, Sustain, Decay and Release.

simple-synthesis-adsr

Here is one simple design for just attack and decay from https://synthnerd.files.wordpress.com/:

Solar-Powered Autonomous Wildlife Photography

This project uses the LTC3105 Solar Harvesting IC from Linear Technologies, an Atmega328P along with a Serial TTL camera and an SD mini card for saving the images.

The plan is to create a waterproof casing for this device and then install it in a nearby forest and set it to take photographs when it sees movement.

Here is the circuit layout and schematic:

THe LTC3105 can supply between 6mA and 12mA which isn’t enough to power the 3.3V SD card which draws 100mA during R/W at 25MHz mode and 200mA during R/W in 50MHz mode. My attempt to solve this issue is to have a voltage divider step down from 5V (which is powering the camera). The voltage divider uses a 3.3K and a 2.2K resistors and should draw .9mA. The camera has 3.3V TTL logic and draws 75mA at 5V. Both the SD card, the voltage divider and the camera are shut on/off by a MOSFET.

The camera will go on the backside of the circuit board along with a 33x37mm solarbotics solar panel possibly acting as a mini roof. The camera pin spacing is 2mm, not the typical.

I am using two Adafruit tutorials and the relevant preexisting Arduino libraries:

https://learn.adafruit.com/ttl-serial-camera/

https://learn.adafruit.com/adafruit-micro-sd-breakout-board-card-tutorial/introduction

The board took an entire day to engrave and there were still many shorts caused by tiny copper hairs, our lasercutter needs to be serviced:

The first step went smoothly, loading a blink code works fine.

Here things started to get difficult.

  1. I didn’t place the ICP header perfectly square in the middle of the pins and didn’t use an SMD header so the reset pin pulled off. (I only realized this after I replaced the Atmega328 on the board and wasted a perfectly good chip…)
  2. I forgot to add a 10K pull-up for the CS, meaning I guess that the SD card could have been disrupting things.
  3. The soldering of the SD card could have gone smoother, I need to check that the contacts are correct. I am placing the board on a soldering plate and using solder paste that melts at around 130 C.
  4. I really need a USART connection to be able to debug this and didn’t break out pins RX and TX unfortunately. My improvised solution might be adding noise to the serial communication.
  5. It appears that when the SD card is plugged in it is not a good idea to program the Atmega328. I get errors when AVR studio writes or reads data.
  6. Of course don’t forget to set the CLKDIV fuse off so that everything works smoothly with Arduino.

After testing with the SD Arduino libraries I had varied success, sometimes it would pass the SD card initialization but then report the wrong size of SD card. I reformated my SD card and that didn’t change anything. I tried a Read Write example code and that didn’t pass the initialization phase.


I found a serious error in my board, I connected both VDD and VSS to 3.3V but in fact only VDD should go to 3.3V. VSS should be connected to ground.

I can get the Ardiuno SD Read/Write code to at least create a file on the SD card now but it also produced a bunch of USART noise:

I’m not sure if the issues are related to my improvised USART connection or something more fundamental in the circuit.


I put the SD card and the Atmega328 on the same power supply, and also checked the connections between the SD card and the microchip (I added a bit of solder to the MOSI pin which wasn’t passing the continuity test with certainty) and now things seem to be working!

As a quick test it seems that if the SD card and the micro share the same ground everything still works even if the SD card is being supplied with a different VCC.

I added the camera and everything seems to work:

And here is the image quality:

And here’s what the current setup looks like:


Getting to the LTC3105 solar power management part of the circuit and have made some errors:

I want LDO (voltage for microchip) to be at 3.3V so it is at the same logic level as the SD card and camera which it will be communicating with. This means I need a resistor divider to select this voltage level. To get 3.3V I am using 1M and 430K (it adds 1V to the ratio).

To set the Vout at 5V I am using 1M+82K and 270K on the other side.

The solar harvester appears to be working! I’m using a single 1F 5.5V super capacitor which is basically two capacitors put together into one package:

The 1F 5.5V super capacitor I am using isn’t performing great, the moment the sun hits a cloud the voltage falls fast. It might be because of the internal resistance of the cap which is 500mOhms. Contrast this with the wasm 10F 3V supercapacitors I used for the RF solar-powered sensor which had only 34mOhms of ESR. However, the fall in stored power might also be related to the fact I’m asking the LTC3105 to bring Vout to 5V, previously I had only tested to 3.3V. I am also using a solar panel in the 3.5V range which is outside the optimal for this chip.


I am now stuck after having soldered the MOSFET and tried to load the code that would test the SD card after having turned on the MOSFET. This involved also a voltage divider connected to Vout which I am not too sure about. I removed the MOSFET and voltage divider and I am still finding a voltage reaching the SD card mysteriously. I think there may be a short between the 3.3V SD card power and a logic pin for instance.

I think I should have used a voltage regulator instead of a resistor divider, Vout fluctuates quite a bit and this may be throwing off the communication with the SD card.

As a sanity check I powered the SD card with a power supply and the microchip with the super cap/LTC3105 and everything works.

I’m using a 3.3V voltage regulator called the LM3480IM3X-3.3/NOPB which can supply 100mA which is just enough for R/W if the SD card is in 25MHz mode.

The SD card works when being powered from the solar cap if it has a voltage regulator. The VR works up until around 4.3V of capacitor charge.

The camera also works, including in motion capture mode. (All these tests are connected to a power supply simulating the solar panel, I’ve yet to have a sunny day for testing. When I disconnect the power the cap drains super fast but I think this is because I’m using a 1F cap which is leaking heavily. I have also not yet tested the MOSFET to turn on and off the camera and SD card.)

After start up the motion control detects motion even if there isn’t any but then appears to settle down later.

I got several photos of my hand which was waving quickly through the camera’s field which I thought was impressive:

But I also got some strange lighting:

…and at least a quarter of the jpegs were corrupt.


Finished the redesign of the board:

Side one:

Side two:

It has the following improvements over Rev.1:

-A USART friendly plug-in location for debugging.

-A nicer breakout of the pins (RX, TX, MOSFET GND and VCC) which need to go to the camera on the flip side (they can be bridged with bent pins)

-A 10K on CS line

-A resistor divider to set LDO to other than 2.2V.

-Corrected SD card Vcc and GND connections.

-A 3.3V voltage regulator for the SD card instead of the resistor divider.

-Generally increasing the size of the board and making certain areas a little less squeezed.

-Not a reset button, as there was not enough space, but a RST pin which can be easily touched to a nearby ground pin.

-A set of traces and a header for easy installation of the camera on the back of the board.

The lasercutter is cutting beautifully:

But when I flip the board over to flip the backside I am cutting through and creating holes:

This one barely survived:

I had similar issues with this board unfortunately. 

I jumped ship and made a modular version, thinking that this would be fool proof:

 

Tiny aside: Wow, a camera which gets energy from the same light it is recording! https://www.discovermagazine.com/technology/this-camera-is-powered-by-light

Drawing Machine

We wanted to make an interactive Draw Bot which would make nice drawings near the entrance of the Fab Lab and invite guests to upload their own drawings too. I am working with our PhD candidate Nawel Khenak on this project.

We downloaded most of the 3D parts from this kit on Thingiverse: https://www.thingiverse.com/thing:798076

But we eventually made our own custom motor mounts by attaching two of these adafruit products together and screwing them into the wall: https://www.adafruit.com/product/1297

We used basic timing pulley wheels (https://www.mcmaster.com/timing-pulley-wheel ) and Nema 17 stepper motors. We spooled a good few meters of the wire to ensure that there wouldn’t be any slipping or running out of line.

After some issues using first a gearbelt (inelegant and not sufficiently flexible), and then a very fine thread (not sufficiently strong), we landed on using conductive thread (https://www.sparkfun.com/products/11791). It is strong and has a nice color also.

We are powering two Easy Stepper Motor Drivers with 12V and using an Arduino Mega.

We’re using Makelangelo for the software: https://github.com/MarginallyClever/Makelangelo-firmware

Image result for makelangelo drawbot interface

In the Arduino code we selected the RUMBA machine and looked at the pinouts for the motor drivers and the servo motor to make the correct connections on the Mega:

#define MAX_MOTORS (5)

#define MOTOR_0_DIR_PIN (55) #define MOTOR_0_STEP_PIN (54) #define MOTOR_0_ENABLE_PIN (38) #define MOTOR_0_LIMIT_SWITCH_PIN (3) /* X min */

#define MOTOR_1_DIR_PIN (61) #define MOTOR_1_STEP_PIN (60) #define MOTOR_1_ENABLE_PIN (56) #define MOTOR_1_LIMIT_SWITCH_PIN (14) /* Y min */

#define MOTOR_2_DIR_PIN (48) #define MOTOR_2_STEP_PIN (46) #define MOTOR_2_ENABLE_PIN (62) #define MOTOR_2_LIMIT_SWITCH_PIN (18) /* Z Min */

#define MOTOR_3_DIR_PIN (28) #define MOTOR_3_STEP_PIN (26) #define MOTOR_3_ENABLE_PIN (24) #define MOTOR_3_LIMIT_SWITCH_PIN (2) /* X Max */

#define MOTOR_4_DIR_PIN (34) #define MOTOR_4_STEP_PIN (36) #define MOTOR_4_ENABLE_PIN (30) #define MOTOR_4_LIMIT_SWITCH_PIN (15) /* Y Max */

#define MAX_BOARD_SERVOS (4) #define SERVO0_PIN (11) /* Servo 1 */ #define SERVO1_PIN (6) #define SERVO2_PIN (5) #define SERVO3_PIN (4)

#define LIMIT_SWITCH_PIN_LEFT (MOTOR_0_LIMIT_SWITCH_PIN) #define LIMIT_SWITCH_PIN_RIGHT (MOTOR_1_LIMIT_SWITCH_PIN)

We commented HAS_LCD from the config file to avoid a problem where the Drawbot gets stuck waiting for the user to click OK on the LCD screen (the “M226” command in the drawing code):

//—————————————————————————— // LCD panels supported //——————————————————————————

#define HAS_LCD // if you have an LCD panel #define HAS_SD // if you have SD card support on your LCD panel (must be on panel?)

// only uncomment one of these options //#define LCD_IS_128X64 // reprapdiscount Full Graphic Smart LCD Controller #define LCD_IS_SMART // reprapdiscount Smart LCD Controller (including XXL model)

Everytime we load the software we need to re-input the parameters of our machine but Nawel is looking into regenerating the Java code with our parameters baked in based on the info at this site: https://github.com/MarginallyClever/Makelangelo-software/wiki/Getting-Started

We are working to rationalize the wire management, right now it’s unsightly:

Currently the wires from the motors go through the ceiling and come through a ceiling tile to our a nifty box that Nawel made.

We are printing Nice clips for wire management: https://www.thingiverse.com/thing:2798689

And also a nice pen-holder that Nawel made:

Fablab RGB LED Sign

 

Image result for new museum new york sanaa

This project has the goal of making the Fab Lab Digiscope location visible from the exterior of the building and meanwhile creating an a display that users can code themselves.

 

After testing with painting tape, it was clear that giant letters made from material would not be sufficient to make the Fablab visible from outside. This led to the idea of illuminating the letters with LEDs.

Each letter will require about 5 meters of LED strip. We chose RGB leds in a strip from Adafruit that were reseanably priced:

https://www.adafruit.com/product/285?length=1

The LEDs are not individually addressable but the strips are RGB and can of course be faded in and out. Because each letter will be a seperate strip, we can have three different colors and brightnesses happening at once, one for each letter. We could potentially design in interface that lets users create animations, or we could invite them to modify the Arduino code directly as well.

Unlike Neopixels the LEDs in a strip will all change color at the same time and there is no microcontroller embedded in the LED strip. An external microcontroller will be needed to vary the PWM signal being sent to the MOSFETs which will control the power for each color in the strips (one for Red, one for Green and the last for Blue). The LEDs are powered by 12V. There are 30 LEDs/meter, 150 LEDs per letter and 450 LEDs in total which will be controlled by one microchip using 9 output pins.

The choice to work with non-addressable RGB LED strips was motivated by the desire to keep the project within a reasonable budget and level of complexity but to also allow users of the fablab to engage with the intricacies of programming three RGB LED colors at varying intensity changing over time. Good taste dictates not having too many garish colors flashing at the same time as well.

In terms of font, I’m thinking something which reflects the history of computation. Proxy lowercase or uppercase:

Inspiration from Troika London:

Image result for the weather yesterday

Image result for new museum new york sanaa

Raster Image Compression/Interlacing/Encoding Index Representation (IN PROGRESS)

How can non experts quickly get an idea of  the way in which our computers see our raster images?

I have previously focused my energy on how vectors are internally represented because I had the impression that pixel-based rasters were always stored in a predictable top to bottom, left to right arrays in computer memory. However, after a bit of Wikipedia research I discovered that pixels in formats JPEG and PNG are resequenced when they are compressed, downsampled/encoded, or prepared to be sent via a slow internet connection. The last process is called (I think?) Interlacing for JPEGs and Progressive Scanning for PNGs. 

This gif from wikipedia describes the Adam7 algorithm sequencing pixels in a 16×16 bitmap image. (https://en.wikipedia.org/wiki/Interlacing_(bitmaps)) – clearly I want to find something which is dependent on user loaded images and does not transform all images equally.

Apparently when JPEGs are Progressively Scanned the resulting sequence of pixels is not the same irrespective of the image. In spectral selection or successive approximation low-frequency components might be sequenced first before higher-frequency components  (citing http://www.libpng.org/pub/png/book/chapter08.html). I.e. the resulting sequence of pixels is not determined by spatial location but by value (color?) of the pixel. 

There also appears to be some zig-zag action that takes place in JPEG encoding (https://en.wikipedia.org/wiki/JPEG) :

So, it might be interesting to look at these images in “exploded index” view (displace the pixels in one dimension to show their place in the index). My plan right now is to use Grasshopper to load an image and be able to manipulate the pixels in space based on their place in the input image index. There appear to be a few different Grasshopper plugins for working with images like Shapediver (https://www.food4rhino.com/app/shapediver), Hedgehog(https://www.food4rhino.com/app/hedgehog) and something developed by Professor Andrew Witt at the GSD which I can’t quite track down at the moment. 

To get the ball rolling though I found a browser-based hex editor called Hexed (https://hexed.it/?hl=en) and began looking at the raw JPEG and PNG data. For PNG the image info is between IDAT and IEND, and there may be several chunks (possibly to make the file more robust in case there is an error in a particular chunk). For JPEG the pixel data is between SOS (0xFF 0xDA) and EOI (0xFF 0xD9). I highlighted one chuck of pixel data in a JPEG image below using Hexed.

I was expecting to find only one image chunk as this image was not saved from Photoshop as “Progressive” but instead I found three chunks. When I save the image as Progressive though I get 9 chunks. Despite saving the image 16×16 with all black pixels I still get a bunch of different hex values for the pixels and I’m not sure why (I thought possibly a CMYK vs RGB situation but a CMYK image at 100% doesn’t make finding a block of pixels with the same value easier for some reason…). So far I am liking PNG files because they are a whole lot smaller.  

 

I just did some tests deleting parts of JPEG and PNG files. I tried removing single bits, and removing chunks. Both resulted in corrupt files which could not be opened.

From https://en.wikipedia.org/wiki/Portable_Network_Graphics:

  • IHDR must be the first chunk; it contains (in this order) the image’s width (4 bytes), height (4 bytes), bit depth (1 byte), color type (1 byte), compression method (1 byte), filter method (1 byte), and interlace method (1 byte) (13 data bytes total).[10]
  • PLTE contains the palette; list of colors.
  • IDAT contains the image, which may be split among multiple IDAT chunks. Such splitting increases filesize slightly, but makes it possible to generate a PNG in a streaming manner. The IDAT chunk contains the actual image data, which is the output stream of the compression algorithm.[11]
  • IEND marks the image end.

If I change the bit value after IHDR I can mess with the width of the image and this leaves a file which is still readable. When I delete multiples of 8 bits from the file it still appears to load fine also and deletes parts of the image and then adds a single row of random colors. 

It looks like the images I have made in Photoshop are 16×16 pixels (256 pixels in total) and have a bit depth of 24. There appear to be three Hex pairs of data per pixel  (for R,G, and B channels[?]) because there are three times as many hex pairs to describe the image pixels as there are pixels in the image (but also confirmed here: http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.4). A Hex pair contains 8 bits worth of data, so 24 bits in total per pixel because that is the bit depth at RGB. Changing the Hex values results in different colors. 

Wikipedia says that only the 3 lower bits of each 8 bits of data is used to describe the color…

OK so after reading the PNG specs I am realizing that things are FAR more complicated than I originally assumed. The IDAT pixel data is compressed by the Zlib deflate algorithm and a kind of custom checksum called a CRC is placed at the end. All of this makes it not possible to edit the raw compressed IDAT without first unzipping it and rezipping it with Zlib before reinserting it into the image.

It looks like there is a Python LibZ tool which is described here: https://stackabuse.com/python-zlib-library-tutorial/

There are also people trying to make their own PNGs and documenting their progress on stack exchange:

https://stackoverflow.com/questions/22672112/png-idat-specification?rq=1

Ah, but I also just realized that if I output a file from Photoshop and select uncompressed it will output a hex stream that more or less directly relates to the pixels in the file. 

By making a new image with a single white dot in a field of black I can then move this white dot around by copy pasting FE FE FE (R,G,B) in the sea of 00 00 00. Apparently this doesn’t cause any issues for the CRC. I can also change the color of any individual pixel by finding the triplet of hex pairs that describes that pixel. This appears to work nicely with 16×16 pixel images of black (white not so much?). I can even find the pixels if the image is white:

02 appears to mark every new line, I could 48 bytes between each 02 (divided by 3 = 16, the number of pixels in each row of the image). 

I have no idea why, but I can’t edit the bottom 1/4 of the image, these two pixels represent the limits of what I can edit.

I failed trying to add an additional row of pixels by changing this value in the IHDR (using Tweak PNG to generate the right CRC once I changed the height of the image in this program) then adding 48 pairs of hex numbers into the IDAT and also changing the CRC at the end of the IDAT using Tweak PNG again. 

I did find these nice visuals to describe the PNG files:

https://www.w3.org/TR/2003/REC-PNG-20031110/

***********

After reading a blog post about glitch art and consulting the Image Glitch App page, I decided to give JPEG, TIFF or BMP a try. 

I found a nice program which allows for inspection of various kinds of image formats called Exiftool:

So this program provdes a ton of metadata about a file, but it’s not really optimized for editing pixel info and reloading. Still, this is useful going forward.

Making a B-line directly for image glitching software I found this handsome program Snorpey:

https://snorpey.github.io/jpg-glitch/

 

 

It makes very pretty glitches, I wonder if I can find out how it is working under the hood and comandeer it’s behavior to my ends…

I am looking through the source code for the program Glitch Canvas (which seems to be the inspiration for this app) here: https://github.com/snorpey/glitch-canvas

Under Sources, there is a glitch Jscript code which does the glitching I think. Before the image is edited it appears to be first translated into a byteArray, other things are determined beforehand like the start of the image data at SOS. At the heart of the code is a loop which appears to iterate over the bytes in the array. The three glitch parameters, seed, amount and iteration, 

Here is the code:

“””

import jpgHeaderLength from ‘./jpgHeaderLength’;

export default function ( byteArray, seed, amount, iterationCount ) {
const headerLength = jpgHeaderLength( byteArray );
const maxIndex = byteArray.length – headerLength – 4;

const amountPercent = amount / 100;
const seedPercent = seed / 100;

for ( var iterationIndex = 0; iterationIndex < iterationCount; iterationIndex++ ) {
const minPixelIndex = ( maxIndex / iterationCount * iterationIndex ) | 0;
const maxPixelIndex = ( maxIndex / iterationCount * ( iterationIndex + 1 ) ) | 0;

const delta = maxPixelIndex – minPixelIndex;
let pixelIndex = ( minPixelIndex + delta * seedPercent ) | 0;

if ( pixelIndex > maxIndex ) {
pixelIndex = maxIndex;
}

const indexInByteArray = ~~( headerLength + pixelIndex );

byteArray[indexInByteArray] = ~~( amountPercent * 256 );
}

return byteArray;
}

“””

So to conclude:

  1. iteration: changes how many times the main loop runs. This will impact how many bytes are rewritten in the image data portion of the image (smaller the iteration, the more loops and the more bytes transformed).
  2. seed: changes how many bytes are skipped over each time the loop runs as it moves from the top to the bottom of the pixel data. (larger the parameter, fewer bytes overwritten because more bytes skipped over).
  3. amount: the value of the new byte which is overwritten each time through the loop. (larger the value, larger the byte value the byte is replaced with).

Clearly I need to learn how the images are prepared as a string of bytes now:

  1. Images are converted into Base64 (6 bits per digit)
  2. Then Base64 is converted to an array of bytes (8 bits per digit)
  3. The bytes are overwritten selectively based on the 3 parameters of the glitching. 
  4. The byte array is recoverted into Base 64.
  5. The Base 65 is recoverted into an image.

Quick note: I like this stepping effect that is created, this could be useful for showing sequence.

JPEGs seem to be just as super compressed and complex as PNGs. (Though they do appear to load even when defective which is way cooler than PNGs). I’m curious about BMP, it seems simpler…

Nice ASCII patterns from this BMP.

I started moving towards Processing for a moment there, it can easily load and manipulate image data. But I have the feeling it resamples image data similar to Grasshopper. There are several example of Processing scripts which sort pixels by color in an image. They are cool but they don’t appear to relate to the original sequence of pixels. (https://steemit.com/art/@granturismo89/how-to-make-amazing-glitch-art-with-processing-and-asdf-pixel-sort or http://datamoshing.com/tag/processing/)

Now I am looking at a website which outlines a series of artistic strategies for datamoshing: 

http://jameshconnolly.com/glitchtalk.html

https://www.glitchet.com/resources

I wonder if I can use my wilderness camera somehow…or hack a digital camera?

RAW files offer the most hackability, they can be saved as a byte array with no header. Different formats start their scanlines in different places on the canvas and sequence RGB differently. Apparently RAW non-interleaved files don’t save pixels sequentially but instead have different layers per color?

compressed files are harder to work with, but they seem the most interesting to visualize because they are going to be messing with the original sequence of bytes and removing data and possibly re sequencing bytes in the process?

She manages to interrupt a Adam7 algorithm to inspect after steps 1-2 (pre-compression) somehow…. 

JPEG have a Run Length Encoding (RLE) which groups together the same frequencies. 

visualizing files by opening them as audio files can quickly show you the overall organization: http://blog.animalswithinanimals.com/2008/09/databending-and-glitch-art-primer-part.html

This author suggests don’t add or subtract bytes to files.

Maybe what I want to be doing is to have a simple processing script that draws pixels from an image file (onto a canvas the size of which I can control) based on a string of bytes (representing the same image) that it reads to get the pixel sequence info.

These are some of the encoding algorithms it would be cool to visualize. I need to find some way to determine the sequence in which these algorithms are processing data:

https://en.wikipedia.org/wiki/Run-length_encoding: runs of data (sequences in which the same data value occurs in many consecutive data elements) are stored as a single data value and count, rather than as the original run. (eg. WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW becomes: 12W1B12W3B24W1B14W)

https://en.wikipedia.org/wiki/Entropy_encoding: replaces each fixed-length input symbol with a corresponding codeword; the most common symbols use the shortest codes.

https://en.wikipedia.org/wiki/Huffman_coding: Makes a frequency tree of content.

https://en.wikipedia.org/wiki/Discrete_Fourier_transform: a  frequency domain  representation of the original input sequence.

https://en.wikipedia.org/wiki/DEFLATE

I should check out the program that processes the TTL serial camera images:

https://learn.adafruit.com/ttl-serial-camera?view=all

Page 20 here has a diagram of the hardware compression:

https://www.st.com/content/ccc/resource/technical/document/application_note/group0/a5/9d/22/46/61/6d/4a/ab/DM00356635/files/DM00356635.pdf/jcr:content/translations/en.DM00356635.pdf

**********

New approach: find python code which compresses images and mess with the code to output what I want.

https://github.com/JoshuaEbenezer/huffman_encoding

This code outputs the list of codes and the integer they replace (the length of the code corresponds to the frequency that integer is found in the image).

Here is an output sample:

116 11111111
119 111111101
129 111111100111
132 111111100110
255 111111100101
149 111111100100111
148 111111100100110
142 111111100100101
171 1111111001001001111
173 1111111001001001110
172 1111111001001001101
194 1111111001001001100111
197 11111110010010011001101
190 111111100100100110011001
209 111111100100100110011000111
213 1111111001001001100110001101
224 111111100100100110011000110011
227 1111111001001001100110001100101
233 111111100100100110011000110010011
236 1111111001001001100110001100100101
240 111111100100100110011000110010010011
241 111111100100100110011000110010010010

This diagram explains it all: https://en.wikipedia.org/wiki/Huffman_coding#/media/File:Huffman_coding_visualisation.svg

If I rebuilt the image in grasshopper, and then used the sequence generated by this algorithm, I could alter the grasshopper version of the image based on the algorithm output. I think the effect would not be very interesting though? The other option is to compress the lines of pixels in the image to the same degree they have been compressed by the algorithm. 

Here is a nice article breaking down Huffman encoding: https://medium.com/iecse-hashtag/huffman-coding-compression-basics-in-python-6653cdb4c476

I could write a processing code which loads an BMP, goes through each pixel in the image comparing it to the Huffman table (which has pixel value and code to replace it with) and then create a new image which either makes the original pixels longer (adding the same pixel value to the right, thus displacing adjacent pixels and pushing them around the frame) or makes runs of the same pixel shorter based on the length of the encoded Huffman table value. This would result in an image which is compressed based on the frequency of the various pixels.

Processing seems to be good at this, as with the pixel sorting example by Kim Asendorf:Image result for kim asendorf mountain tour"

And here is a primer for dealing with images in Processing: https://www.processing.org/tutorials/pixels/

The other approach of sampling a JPEG compression chip could head towards this kind of product: http://pdf.datasheetcatalog.com/datasheets/120/130181_DS.pdf

It has a test mode where the user has access to all internal memory.

From https://cscie12.dce.harvard.edu/lecture_notes/2007-08/20080312/slide19.html:

The GIF to the right is twice the size of the GIF to the left because GIF LZW compresses horizontal pixels of the same color:

horizontal linesvertical lines

Here is a nice article on LZW compression: https://marknelson.us/posts/2011/11/08/lzw-revisited.html . Here is a dictionary or look-up table from Alice and Wonderland that was created by the “greedy” algorithm (which looks for the longest string to replace?),

34830 : 'even\n'
34831 : '\nwith t'
34832 : 'the dr'
34833 : 'ream '
34834 : ' of Wo'
34835 : 'onderl'
34836 : 'land'
34837 : 'd of l'
34838 : 'long ag'
34839 : 'go:'

LZW compression apparently outputs the library along with the compression files. So this could be opened in order to see which sequence of pixels is the most oft repeated.
Retro article describing compression techniques: https://www2.cs.duke.edu/courses/spring03/cps296.5/papers/welch_1984_technique_for.pdf

This site has really helpful animations for dictionary creation: http://www.data-compression.com/index.shtml. Check this one out explaining Huffman encoding: 

could try to visualize series of repeated pixel patterns and the "live" processing of these by different algorithms, some greedy others with different priorities?

Check out this stuff on frame buffers:
This is a CRT screen showing it's memory from wikipedia https://en.wikipedia.org/wiki/Framebuffer:

and this is the color palette for an image:
Adaptative 8bits palette sample image.pngAdaptative 8bits palette.png

still from Wikipedia, here is that same image given the wrong color index:


gzthermal is a psuedo heatmap that shows the words that get  compressed and those that don't
 https://encode.su/threads/1889-gzthermal-pseudo-thermal-view-of-Gzip-Deflate-compression-efficiency:
Image result for deflate image compression visualization"

here is a visualization of LZ77 by Canadian programmer   Julia Evanshttps://jvns.ca/blog/2013/10/24/day-16-gzip-plus-poetry-equals-awesome/

Solar Business Cards

Inspired by the various existing designs of PCB business cards, we were inspired to make a similar thing for Fablab Digiscope.So far there have been popular business card projects which have had LED patterns display, have miniature screens, Magic 8-ball prediction capabilities, act as MIDI controllers, others bring up a text file on a computer when pluged in to USB or offer file storage.

Starting with the constraints:

-We have single and double sided small PCB boards which are business card shaped at 76mm x 50.7mm. However there is also the possibility of working in card stock and laminating vinyl-cut double sided copper tape.

-Because it takes at least 15 minutes to make a single raster pass on a board this size (and around 8 passes to completely ablate the copper), chosing a smaller space on the board to actually engrave is the only way to make this project possible with our time constraints. This may also be another opportunity to revisit earlier tests using the lasercutter in vector mode but this time to offset the vector (by how much?) at least once (probably thrice) to make sure their are no copper bridges this time. This would allow more compositional designs.

-We want to have our name and address written on them “Digiscope Fablab, 630 Rue Noetzlin, 91190 Gif-sur-Yvette” or perhaps just our website “https://fablabdigiscope.gitlab.io/” or just perhaps the logo!

-It has to look cool (composition is an element of the PCB business card “genre”) and/or do something cool!

-Business cards have to be flat – but they can of course pop-out and become 3D at some point. This means that anything soldered to the card also has to be flat. The big question is about batteries, they add thickness, weight but also inelegance, in my opinion. Perhaps the power should come from USB?

-it must have a sufficient number of components to look “technological”.

-obviously to be cost effective the price per card definitely can’t exceed a few dollars.

What it could do:

-a usb device which stores important information for fablab users, such as the fablab charter, information about our website, address, etc. in a text file. The problem I have with making usb connectors out of the edge of boards is I find they don’t work very well.

-a mini pair of joysticks and leds to make some kind of light/memory game.

-a very simple 1381 miller solar engine circuit which causes the card to vibrate every few seconds when in the sun. I like this idea because it associates the lab with clean energy and I find the solar kit I made to be the one which interests people the most immediately.

Technically: this would require SMD versions of the 1381/MCP112 (easy), the 2907 (super expensive), the 2222 (super expensive) and, more importantly, an Aluminum Electrolytic Capacitor SMD version of an 2200uF cap (another cap option is to have four 560uF SMD Aluminum Electrolytic caps in parallel). This raises the question if it’s possible to substitute the transistors with MOSFETs or if using through hole components…

This website: https://www.fetchmodus.org/projects/beam/photopopper/ has an interesting circuit which involves switching the transistors for low-gate-turn-on-voltage MOSFETs (DMN2215UDM-7) which are much easier to find in SMD form. The designer also uses gigantic tantalum capacitors (1500uF!) which are flat. These unfortunately cost 7+ euros each on Mouser. However this circuit appears to be represent an SMD version of the classic solar engine. The designer also uses an alternate of the MCP112 voltage trigger in the ISL88001 which require only 160nA to test the voltage.

In terms of cost:

$2 – single solar panel (from Digikey) $1 – ISL88001 $0.4 – DMN2215UDM-7 $2 – vibrating motor (but we have plenty lying around the lab so they are free-ish!) $3 – compact 3000uF capacitor (only .90 for a larger capacitor – how important is it to make it tiny?) $1 – for the circuit board

under $10USD but that’s a little on the expensive side…

Trying to optimize for cost.

$2 – single solar panel (from Digikey) $1 – ISL88001 $0.4 – DMN2215UDM-7 free – vibrating motor (we have plenty lying around the lab so they are free-ish!) $0.6 – 1000uF capacitor (smaller cap maybe will make less annoying vibrations also) $1 – for the circuit board

$5USD total is not horrible?

Here are some tests with the composition:

Here is my first shot at the circuit:

Here is an attempt at the USB version:

I gleaned the circuit from various available online:

From the internet I got some answers about the components in the circuit:

The USB signal operates at around 3.3V D- needs pulling up (via 1K5) to signal the presence of a USB device The current limiting resistors (68ohm) protect the microchip from a large current sink by the zeners and also serve the function of a termination resistor for the USB (which is supposed to be around 20ohms). V-USB is the firmware of choice for turning avrs into USB devices it seems.

I’m interested in finding an aesthetic language with the lasercutter PCB engraving process we have at the lab. My instinct is that by pulling a thin layer of yellow paint into an engraved path we can make some text that will really stand out.

With the single-sided board there is a nice effect when looking from the reverse and seeing the yellowish-looking traces.

I tried to do an acetone transfer on both sides of the PCB but that yeilded poor results.

One thing I discovered is that you can lasercut out text and then pass a soldering iron and solder over it to silver-ize it. This means you can have two “colors”, copper and silver. If the text were thicker the effect would be more striking.

I’m concerned about how easy this will plug into a usb jack. In fact in the single sided mode it’s far too thin to insert so it looks like a double-sided board is required or a usb male connector.

Some tests cutting out of metal fabric/tape:

The only way one of the lasercutter produced boards looks good is when it is crammed with components, then the components visually take precedence over the charred background. I am retrying the business card but in a much smaller area to eliminate the visual effect of the majority of the object being charred fiberglass (it also means we can make more of them faster). I’m doing this on double sided board so it is the right thickness for a usb plug. (The double sided board looks less bad with the copper removed, more like mdf than charred matrix).


The parts have arrived, here is an adapted version of Nick Ames’ circuit (https://www.fetchmodus.org/projects/beam/photopopper/):

Here are the specs for the two special ICS:

And here is the PCB:

It turns out with some testing that with these 2V solar panels the minimum is a couple of panels in series along with a 1000-1500uF normal or SMD tantalum capacitor. I’m rearranging the board to accomodate two solar panels and only one capacitor.

If I could do the order again I would have taken the 4.46V KXOB25-01X8F instead of the 2.07V KXOB25-05X3F-TR and then it might have been possible to pull of the card with only a single panel. It might have been smart to take a lower voltage version of the voltage trigger (2V instead of 2.9V maybe).

For the interest of time it seems silly to engrave a large board only to use a portion for the circuit. It might be possible to cut a smaller board and integrate it into a cardstock business card form. This could be achieved by delaminating a part of the business card and installing the circuit board there.

Here is the board assembled and working (after a long debug which concluded that there was a short under a capacitor in the board. Better checking of the board before soldering being the solution.)

Here are some options for how the circuit could be integrated into a business card:

And here is a mock up of what the card could look like:

Talking with our doctorat student Nawel she had some ideas for how to improve this prototype:

-why not lasercut the card itself, and make the card represent a hybrid of everything that is possible to make in the fablab? Printing the card on card is not easy to do in the lab. -we could 3D print a kind of stand that cool keep the card standing up so that the panels face the sun.

I don’t mind that the card won’t “work” unless it’s sunny, but it would be nice to have a lamp which would allow us to show how it works when there is sun when it is overcast.

The associations with the card that are good for us are the renewable energy element and the designing with a connection to nature. It’s also nice that the card vibrates – the card is suggesting it is associated with dynamism and that the fablab is by extension a dynamic place.

The USB version of the card for me is kind of dead as it leads to a series of driver issues with certain kinds of windows which is not optimal.

Here is a result I am happy with:

Here is how it all fits together and folds to stand upright:

Making the first run of multiples to check how easy the process is.

The effect of having six of these boards in your hard when the sun out is quite something. It’s as if they are a swarm of bees.

I changed the laser lens and got about ten times more power. I switched from 1200DPI to 600DPI and increased power to 8/100/1 from 16/100/1. Here is the 8-bit effect of the DPI change:

I originally thought it would be neat to combine acetone ink transfer with lasercutting but the results were dissapointing:

Here’s the final prototype:

*********

This project clearly needs to move in the direction of paper PCB or acrylic substrates:

Debugging

 

I like to draw out my circuits and then color over the lines after I’ve soldered them or re-checked them.

I really enjoyed this overview of electronics debugging made by MIT TA D. Elliott Williams: http://web.mit.edu/6.101/www/reference/TheArtofDebuggingCircuits.pdf

Here is a summary of the main thinking as I see it:

-Circuits cannot be wrong, if there is a problem it is “either be because you do not understand what you built or you did not build what you understand.”

-You must first understand how a circuit works before you can debug it. If you are using components, understand the datasheets.

-To debug a circuit, first establish what it is doing, this narrows the list of possible errors down considerably.

-Think, what could cause this type of behaviour? Make a list of possible causes and cross them off one by one.

-Get a fresh pair of eyes on your problem.

-Systems are composed of sub-systems. Isolate sub-systems and test them each in isolation.

-Build your circuit neatly and logically, this makes it easy to check connections and reduces noise from entering long wires.

-Use the continuity mode on your multimeter to test connections.

-Make sure you are not misusing your oscilloscope (check the x1/x10, if in DC/AC coupling, that the ground clips are attached to ground, )

-Rebuild your circuit but with all different components on a different breadboard.

RF communication with the RFM12B module

 

(For the working code scroll all the way to the bottom!)

I free-formed a simple RFM12B atmega168 temperature sensor circuit using a 3.7 lithium ion battery I would one day like to solar recharge. Behold!:

Notes: DO for Data Out and DI for Data In, from the perspective of the RFM12B. I’m using a 7cm long antenna because these modules are 868MHz (you can tell the frequency based on the existence or not of a certain capacitor).

The MISO line is dead, the RFM12B is not responding to anything I’m sending it…

The RFM works with 16 bit data and I am currently trying to squeeze two 8 bit data transmissions, this is why I think things are not currently working. This project might be the limit of where it is easy to make one’s own code and when one must rely on code produced by the manufacturer of the chip in question.

An additional problem with the particilar project is the poor documentation by the manufacturer of the RFM12B module. Even the numbering of the registers is not consistent and there are errors in example code.

Here is the (not yet working) TX side code:


// *
// * Atmega168 RFM12B TX
// *
// * Created:
// * Author : FablabDigiscope
// */

#define F_CPU 8000000

#include <avr/io.h>
#include <util/delay.h>

#define NIRQ PB0 // input for nIRQ which goes low after a transmit is received?


void SPI_Init();
void SPI_Transmit(char dataout);
void SPI_Stop();
void rfInit();


int main(void)
{
		SPI_Init();
		SPDR = (0x00); // byte to send
		SPDR = (0x00); // byte to send
		rfInit();
		DDRD = 0b10000000; //LED for RX/TX rec/sent

	while (1)
	{
		char dataout = 0b10011001; // 0x99 //
		

		
		SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.		
		SPI_Transmit(0xAA); // PREAMBLE
		
		SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
		SPI_Transmit(0xAA);
		
		SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.		
		SPI_Transmit(0xAA);
		
		SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.		
		SPI_Transmit(0x2D); // SYNC
		
		SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
		SPI_Transmit(0xD4); // Network ID


		SPI_Transmit(0xB8); //this must precede data, it is the transmit register write command.
		SPI_Transmit(dataout);
		
		SPI_Transmit(0x00); //
		SPI_Transmit(0xAA); // DUMMY BYTES, optional?
		
		SPI_Transmit(0x00); //
		SPI_Transmit(0xAA);
		
		SPI_Transmit(0x00); //
		SPI_Transmit(0xAA);
		
		SPI_Stop();

		_delay_ms(1);
		
		PORTD = 0b10000000; // turn on LED

	}
}



void SPI_Init()
{
	DDRB = ((1<<DDB2)|(1<<DDB5)|(1<<DDB3)); //SPI pins on port B: SS, SCK, MOSI outputs
	//set MISO as input
	PORTB |= (1<<DDB2); //start with SS high (slave not selected). DO THIS BEFORE BEGINING ISP
	PORTB |= (1<<DDB4); //MISO pull-up activated
	SPCR = ((1<<SPE)|(1<<MSTR)|(1<<SPR1));  // SPI enable, Master enable, f/64. DO THIS AFTER DDR!
}

void SPI_Transmit(char dataout)
{
	//SPI_Transmit
	PORTB &= ~(1<<D