homebrew processors and film camera love

Make Your Own – Part 4 – Rest of Code

Make Your Own – Part 4 – Rest of Code

This is a LONG page, take time to do each bit in sections to get your head around it all.

Agitation Timing

This for me, was the hardest part to get my head around as I just don’t understand how millis settings work in arduinos.

I actually hired someone from India for a £20 to write this part for me, then once shown, I can understand how to edit the code to adjust my timings.

//dev cycle set to rpx400 time of 6m30s
void monoDevCycle() {
uint32_t monoDevcountdown = 300;
uint8_t monorelayCountdown = 30;

bool runningmonoDev = true;
bool updateDisplaymonoDev = true;
uint32_t countdownTimemonoDev = millis();
uint32_t relayOnTimemonoDev = 5;
uint32_t relayOffTimemonoDev = 25;
bool relayStatemonoDev = true;

//-enter the servo function below
agitationOn();
while (runningmonoDev) {
if (updateDisplaymonoDev) {
updateDisplaymonoDev = false;
lcd.setCursor(0, 2);
char m[3];
char s[3];
sprintf(m, "%02d", int(monoDevcountdown / 60));
sprintf(s, "%02d", monoDevcountdown % 60);
lcd.print(m);
lcd.print(":");
lcd.print(s);
//Below is the countdown in minutes and seconds for 7segment display
byte monoDevminutes = (monoDevcountdown / 60);
byte monoDevseconds = (monoDevcountdown % 60);
display1.printTime(monoDevminutes, monoDevseconds, true); // display time

if (relayStatemonoDev) {
lcd.print(" Agitating");
}
else {
lcd.print(" Standing");
}

lcd.setCursor(0, 4);
if (relayStatemonoDev) {
lcd.print("AGI stops in ");
}
else {
lcd.print("Next AGI in ");
}
sprintf(s, "%02d", monorelayCountdown);
lcd.print(s);
}

// Every second: count down.
if (millis() - countdownTimemonoDev > 1000) {
if (monoDevcountdown == 0) { // Finished! (this happens after the last second has passed).
runningmonoDev = false;
}
monoDevcountdown--;
monorelayCountdown--;
countdownTimemonoDev += 1000;
updateDisplaymonoDev = true;
if (monorelayCountdown == 0) { // Switch the relay.
if (relayStatemonoDev) {
//enter the servo off function below
agitationOff();
relayStatemonoDev = false;
monorelayCountdown = relayOffTimemonoDev;
}
else {
//enter the servo on function below
agitationOn();
relayStatemonoDev = true;
monorelayCountdown = relayOnTimemonoDev;
}
}
}
}
lcd.clear();
display1.clear();
}

The above is alot to take in, but the only bits we are interested in are as follows

uint32_t monoDevcountdown = 300;
uint8_t monorelayCountdown = 30;

This sets the overall time in seconds, and the interval between agitations (or starting the relay)

uint32_t relayOnTimemonoDev = 5;
uint32_t relayOffTimemonoDev = 25;

The above may need changed if you wish to adjust the agitation timing.

//enter the servo off function below
agitationOff();
relayStatemonoDev = false;
monorelayCountdown = relayOffTimemonoDev;
}
else {
//enter the servo on function below
agitationOn();
relayStatemonoDev = true;
monorelayCountdown = relayOnTimemonoDev;

And the above shows the process calling the agitation relay commands we covered earlier.

And that’s it for the agitation timing. I’d be lying if I said I fully understand the above, but it works and is enough for me.

You can easily replicate the above code for every timing agitation part needed. You need to use find and replace and change each ‘mono’ to another word to avoid the commands failing due to being called the same.

Putting it all together

This isn’t hard, but I would do this very slowly in order that you don’t get mixed up.

Make your process commands

The first thing you need to do is make all the commands for the processes that will be called when you stitch them altogether.

Let’s use an easy process as an example. Mono Development.

You would need to make 3 programs (void etc), one agitation section for Developer, One for Stop Bath and one for Fixer.

In my code they are called

void monoDevCycle
void monoStopCycle
void monoFixCycle

These are just 3 of the agitiation cycles above, copied and modified to change the time of each process and the names. That’s it really.

Stitch it together

Ignoring button presses to call programs, we can now look at the Mono Cycle program in full

void monoProgram() {

lcd.clear();
lcd.setCursor ( 0, 0 ); // go to the 2nd line
lcd.print("Set Bath to 20c");
lcd.setCursor ( 0, 1 ); // go to the 2nd line
lcd.print("When 20c Reached");
lcd.setCursor ( 0, 3 ); // go to the 2nd line
lcd.print("Start will Light");

// - Temp Start Code

while (digitalRead(25) == LOW) {
// Do nothing
}
digitalWrite(Relay_5, RELAY_ON);
soundBuzzer();

// - Start button press code - Modded for awaiting temp trigger

while (digitalRead(31) == HIGH) {
// Do nothing
}
digitalWrite(Relay_5, RELAY_OFF);

lcd.clear();
lcd.setCursor ( 0, 0 ); // go to the 2nd line
lcd.print("Process Start!");
lcd.setCursor ( 0, 1 ); // go to the 2nd line
lcd.print("Pour in Dev");
lcd.setCursor ( 0, 2 ); // go to the 2nd line
lcd.print("Then Press Start");
delay(1000);

// - Start button press code
digitalWrite(Relay_5, RELAY_ON);
while (digitalRead(31) == HIGH) {
// Do nothing
}
digitalWrite(Relay_5, RELAY_OFF);

lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print("Mono Dev Cycle");
monoDevCycle();
lcd.clear();
lcd.print("Cycle Finished");
digitalWrite(Relay_7, RELAY_ON);
soundBuzzer();
lcd.setCursor ( 0, 1 ); // go to the 2nd line
lcd.print("Drain Dev then,");
lcd.setCursor ( 0, 2 ); // go to the 2nd line
lcd.print("Fill Stopbath");
lcd.setCursor ( 0, 3 ); // go to the 2nd line
lcd.print("Then Press Start");

// - Start button press code
digitalWrite(Relay_5, RELAY_ON);
while (digitalRead(31) == HIGH) {
// Do nothing
}
digitalWrite(Relay_5, RELAY_OFF);
digitalWrite(Relay_7, RELAY_OFF);

lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print("Mono Stop Cycle");
monoStopCycle();
lcd.clear();
lcd.print("Cycle Finished");
digitalWrite(Relay_7, RELAY_ON);
soundBuzzer();
lcd.setCursor ( 0, 1 ); // go to the 2nd line
lcd.print("Drain Stop then,");
lcd.setCursor ( 0, 2 ); // go to the 2nd line
lcd.print("Fill Fixer");
lcd.setCursor ( 0, 3 ); // go to the 2nd line
lcd.print("Then Press Start");

// - Start button press code
digitalWrite(Relay_5, RELAY_ON);
while (digitalRead(31) == HIGH) {
// Do nothing
}
digitalWrite(Relay_5, RELAY_OFF);
digitalWrite(Relay_7, RELAY_OFF);

lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print("Mono Fixer Cycle");
monoFixCycle();
lcd.clear();
lcd.setCursor ( 0, 0 ); // go to the 2nd line
lcd.print("Cycle Finished");
digitalWrite(Relay_7, RELAY_ON);
soundBuzzer();
lcd.setCursor ( 0, 1 ); // go to the 2nd line
lcd.print("Now wash film");
lcd.setCursor ( 0, 2 ); // go to the 2nd line
lcd.print("Using Ilford Wash");
lcd.setCursor ( 0, 3 ); // go to the 2nd line
lcd.print("Process Finished");
digitalWrite(Relay_7, RELAY_ON);
soundBuzzer();
digitalWrite(Relay_4, RELAY_OFF);
}
 

Now it looks alot to take in, but have a slow look down the code. Do you notice it’s mainly just messages printed on the LCD, buttons waiting to be pressed and alot of delays?

All the main program does is display instructions on screen, then awaits the user to press the correct button, ie. start, etc. Then it will call the correct agitation sequence. When that sequence (void program) is finished, it then changes the message on the screen and awaits the next program start via push button (giving you time to change the liquids)

Theres also a buzzer which sounds via another called small program.

Let’s break it down more

// - Start button press code
digitalWrite(Relay_5, RELAY_ON);
while (digitalRead(31) == HIGH) {
// Do nothing
}
digitalWrite(Relay_5, RELAY_OFF);
digitalWrite(Relay_7, RELAY_OFF);

lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print("Mono Stop Cycle");
monoStopCycle();
lcd.clear();
lcd.print("Cycle Finished");
digitalWrite(Relay_7, RELAY_ON);
soundBuzzer();
lcd.setCursor ( 0, 1 ); // go to the 2nd line
lcd.print("Drain Stop then,");
lcd.setCursor ( 0, 2 ); // go to the 2nd line
lcd.print("Fill Fixer");
lcd.setCursor ( 0, 3 ); // go to the 2nd line
lcd.print("Then Press Start");

So above, is one section of common code. Looking at it, its awaiting the Start button to be pressed

while (digitalRead(31) == HIGH) {
// Do nothing
}

The once its pressed, it continues with the loop, it shows on the LCD it’s starting the Stop Cycle, then it calls the monoStopCycle(); program.

Once this agitation program ends, it prints the message on the LCD and sounds the buzzer. It then shows the final instructions on the screen, then the next bit of code (the fixer section) would take over.

If you break each section down like this you can eventually understand that it is all just one giant flow chart.

By now, if you have understood and followed the instructions correctly you will have a basic working, semi automated dev helper!

Hope this has helped, remember this isn’t an exact how to, more a over view guide. You need basic arduino experience to slot it altogether.

Thanks again

By building this I now have the understanding to move onto the fully automated system.