Automatic Toilet Pass Printer

Hi everyone. I am new here so hopefully don’t overstep, but i am chasing a little bit of direction for a project i would like to tackle with some of my students to make teachers lives easier.

At our school teachers must write a toilet pass for each student wanting to go to the bathroom so there is no confusion when they are out of class. This is a good thing, but it is time consuming. It can be very disruptive to a lesson to have to stop and write out a slip every 5 minutes.

What i am hoping to get some direction on is an idea to roughly automate this. Is there a way to use an arduino to keep track of the time and then on a button push, print out a slip of paper (thermal printer i guess) with the current time and teacher/class details.

I can sort of see how it could work with aruduino, rtc, thermal printer, etc. but i am so new to it all it’s a bit hard to know where to start.

If anyone can point me towards something that is at least roughly similar that i can learn from that would be awesome.

thanks in advance.

2 Likes

Hi Andrew,

Welcome to the forum!! Sounds like an awesome project :smiley:
Don’t worry, you’re definitely not overstepping. We’re happy we can help out!

The first point of any project should be a bit of planning so you know what to do when parts arrive.
Some questions that might be worth answering:

  • How do you want to select what class/teacher should be printed? RFID tags? A Menu?
  • How accurate does the time have to be?

Also before grabbing parts I’d check out the guides for the key bits of hardware i.e. pick the Arduino board based on the printer’s requirements.
I’d check out this thermal printer from Adafruit, they have some good guides and work through different examples https://core-electronics.com.au/search/?q=thermal+printer

Let us know if you have any other questions!
Liam.

2 Likes

Hi Liam,

Thanks for your quick reply. I followed the link to the adafruit printer and saw they had done a few tutorials with similar (if more complicated) things so I think I will work through all that as a starting point, then grab one of those units and whatever else I need and give it a go. Thanks again for such a quick and helpful reply.

2 Likes

I am so close to having this finished it’s not funny. I have a DF Robot thermal printer hooked up to an arduino uno, a ds3231 rtc and 3 buttons. Everything is working as it should except the time is printing without the zero’s in the minutes. ie; instead of 16:04 it’s printing 16:4

I am at a loss as to what i have done to cause this so i am hoping someone here might be able to shed some light on the error.

my code is below (hopefully it displays correctly), any help would be greatly appreciated. Be gentle, i have no idea what i am doing :slight_smile:

#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"
#include <Wire.h>
#include <RTClib.h>
#define TX_PIN 6 // DFRobot  GREEN WIRE  labeled RX on printer
#define RX_PIN 5 // DFRobot   YELLOW WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor
 

const int btnPin1 = A0;
const int btnPin2 = A1;
const int btnPin3 = A2; 
int btnVal1 = 0;
int btnVal2 = 0;
int btnVal3 = 0;

RTC_DS3231 rtc;

char string[5][85] = {"test 1", "test2", "test3", "test4"};

void setup() {
pinMode(btnPin1,INPUT_PULLUP);
pinMode(btnPin2,INPUT_PULLUP);
pinMode(btnPin3,INPUT_PULLUP);


  // DFRobot BLUE WIRE TO 7
  pinMode(7, OUTPUT); digitalWrite(7, LOW);

  // DFrobot needs 9600
  mySerial.begin(9600);  // Initialize SoftwareSerial

  // SETUP RTC MODULE
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1);
  }

  // automatically sets the RTC to the date & time on PC this sketch was compiled
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  
  printer.begin();        // Init printer (same regardless of serial type)
  printer.println("Test print.");
  Wire.begin();
 
 
  printer.sleep();      // Tell printer to sleep
  delay(3000L);         // Sleep for 3 seconds
  printer.wake();       // MUST wake() before printing again, even if reset
  printer.setDefault(); // Restore printer to defaults
}

void loop() {
DateTime now = rtc.now();
btnVal1=analogRead(btnPin1);
if(btnVal1<200){ // We press the white bathroom push button
 printer.println(F("------------------------------"));
 printer.setSize('L');
 printer.justify('C');
 printer.println(F("Bathroom Pass"));
 printer.print(F("Date:  "));
 printer.print(now.day(), DEC);
 printer.print("/");
 printer.print(now.month(), DEC);
 printer.println(F(""));
 printer.setSize('M');
 printer.println(F("This student has permission to"));
 printer.println(F("go to the bathrooms in L BLOCK."));
 printer.justify('C');
 printer.println(F("Left class at:"));
 printer.print(now.hour(), DEC);
 printer.print(":");
 printer.println(now.minute(), DEC);
 printer.println(F("Pass valid for 5 minutes."));
 printer.justify('L');
 printer.println(F("Thank you,"));
 printer.justify('C');
 printer.doubleHeightOn();
 printer.println(F("  MR. PATRICK  "));
 printer.println(F(""));
 printer.doubleHeightOff();
 printer.println(F(""));
 printer.println(F("------------------------------"));
 printer.println(F("Quote of the day:  "));
 printer.println(string[random(0, 5)]);
 printer.println(F(""));
 printer.println(F("------------------------------"));
 printer.println(F(""));
 printer.println(F(""));
}

btnVal2=analogRead(btnPin2);
if(btnVal2<200){ // We press the blue drink push button
 printer.println(F("------------------------------"));
 printer.println(F(""));
 printer.setSize('L');
 printer.justify('C');
 printer.println(F("Drink Pass"));
 printer.print(F("Date:  "));
 printer.print(now.day(), DEC);
 printer.print("/");
 printer.print(now.month(), DEC);
 printer.println(F(""));
 printer.setSize('M');
 printer.println(F("This student has permission to"));
 printer.println(F("get/fill up a drink."));
 printer.justify('C');
 printer.println(F("Left class at:"));
 printer.print(now.hour(), DEC);
 printer.print(":");
 printer.println(now.minute(), DEC);
 printer.println(F("Pass valid for 5 minutes."));
 printer.justify('L');
 printer.println(F("Thank you,"));
 printer.justify('C');
 printer.doubleHeightOn();
 printer.println(F("  MR. PATRICK  "));
 printer.println(F(""));
 printer.doubleHeightOff();
 printer.println(F(""));
 printer.println(F("------------------------------"));
 printer.println(F("Quote of the day:  "));
 printer.println(string[random(0, 5)]);
 printer.println(F(""));
 printer.println(F("------------------------------"));
 printer.println(F(""));
 printer.println(F(""));
}

btnVal3=analogRead(btnPin3);
if(btnVal3<200){ // We press the red office push button
 printer.println(F("------------------------------"));
 printer.println(F(""));
 printer.setSize('L');
 printer.justify('C');
 printer.println(F("Office Pass"));
 printer.print(F("Date:  "));
 printer.print(now.day(), DEC);
 printer.print("/");
 printer.print(now.month(), DEC);
 printer.println(F(""));
 printer.setSize('M');
 printer.println(F("This student has permission to"));
 printer.println(F("go directly to the OFFICE."));
 printer.justify('C');
 printer.println(F("Left class at:"));
 printer.print(now.hour(), DEC);
 printer.print(":");
 printer.println(now.minute(), DEC);
 printer.println(F("Thank you,"));
 printer.justify('C');
 printer.doubleHeightOn();
 printer.println(F("  MR. PATRICK  "));
 printer.println(F(""));
 printer.doubleHeightOff();
 printer.println(F(""));
 printer.println(F("------------------------------"));
 printer.println(F("Quote of the day:  "));
 printer.println(string[random(0, 5)]);
 printer.println(F(""));
 printer.println(F("------------------------------"));
 printer.println(F(""));
 printer.println(F(""));
 }
}
2 Likes

Instead of building the print line bit by bit, create it in memory as a character array and print it in one statement. This is the code example from here:

char buffer [16];
uint8_t sec, min, hour;
sec = now.second();
min = now.minute();
hour = now.hour();
sprintf (buffer, "Time: %02u:%02u:%02u\n", hour, min, sec);
Serial.print (buffer);
2 Likes

thanks heaps for getting back to me so quick. that certainly looks like what i am looking for. As i said, i have no idea what i am doing, so ive just tried to piece this together from bits and pieces i have found. To clarify, my code below needs to be replaced with the code you copied, or to make it work in my program would i break it up and replace the print stuff in the loop but add the other stuff up the top? (i am so new to this i can’t think what the guff is called before the setup.)

 printer.println(F("Left class at:"));
 printer.print(now.hour(), DEC);
 printer.print(":");
 printer.println(now.minute(), DEC);

thanks for your help and patience!

2 Likes

Yes. The example needs to be modified so that the buffer is big enough for your longer text (“Left class at:” instead of “Time:”) and because you are only printing hour and minute, not second (remove “:%02U” and “, sec”). The date will require similar changes. You can just make the buffer an arbitrary large enough size, and use the same buffer for both prints.

You would probably get away with not copying the clock data into the new variables (sec, min, hour) but it is good practice. The Arduino reference is very poor at documenting the data types of functions - copying the return value into a local variable makes it quite clear what data type you are using (unit8_t in this case).

2 Likes

awesome, thanks again.

2 Likes

The time is printing perfectly now, thank you for that help. I have however discovered another issue, which i assume is related to the below;

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

I believed this was meant to set the date and time on the RTC to the date/time of the pc the sketch is uploaded from, then it would keep that time courtesy of the battery, however it seems if i disconnect the arduino power (not touching the rtc battery at all) when i plug it in again it reverts back to the time from the upload. ie; if i upload the code at 9:00am, i can use it and the time continues to track forwards. if i then disconnect the arduino power supply, and reconnect it later, the time goes back to 9:00am.

If anyone has some advice as to where i have gone wrong (i assume it is the code at the top of this post) and can point me in the right direction to find a solution that would be wonderful, then i can finish this up, put it in a nice box with some shiny buttons and start using it in class.

again, thank you to all who take the time to read and reply, you guys are awesome.

1 Like

Once you have set the time, using that line of code or another application that allows you to set it manually, then comment out that line and re-upload the sketch. Subsequent startups will not attempt to set the time.

1 Like

brilliant, a nice easy fix, thanks heaps!

Finished. I learned a heap about arduino, python, RTCs, thermal printers and 3D printing through this exercise, well worth it, and a big thank you for the help from this forum.

One further question, would the code work on a nano as is if i want to shrink it down to a smaller overall footprint? or are there particular changes that need to be made between the two? ie; rx,tx etc.

1 Like