Welcome! Log In Create A New Profile

Advanced

Add password/lock screen to firmware

Posted by evo85210 
Add password/lock screen to firmware
March 06, 2019 08:53AM
This will proabbly be a weird question, I have a atom 2.0 printer, and i'm trying to add a lock screen to the the boot sequence.
but I'm having a hard time understanding the sketch.
I'm trying to use the following tutorial as a starting point:
[www.instructables.com]

and I realised, i got no idead how to initialise the LCD screen, because the board is custom, and there's no pin labelling.
and also, the printer only have a push-turn knob, there's no keypad.

here is the firmware:
[www.atom3dp.com]

What I know so far is that I should put the code in the setup() function in the file Marlin_main.cpp, just after line 507.
I'm basically new to arduino and marlin, so I don't really know what I'm doing, if someone can give me some pointers.
Re: Add password/lock screen to firmware
March 06, 2019 07:57PM
I would aim a little lower (especially with your lack of experience)

the config files says it has a standard REPRAP_DISCOUNT_SMART_CONTROLLER ie a 20x4 char display

but importantly It has a encoder with button

I would suggest implementing a combination lock, this requires no extra soldering or parts. Its just firmware (also means that anyone with standard parts can potentially help you)

So basically it prompts for a password, and displays a number, you rotate the encoder left or right to set the number you want. and select by pushing the button,
The number is then replaced with ** (to try an stop people looking over you shoulder)
You then enter the next number
repeat with as many numbers as you want.

I would recommend numbers from 00-99 and at least 3 of them.

I quite like this idea... and if I get time have a play with implementing it tonight...
Re: Add password/lock screen to firmware
March 06, 2019 09:36PM
gah, first issues is the firmware is wont even verify (compile) right out of the archive....

in cmdbuffer.h

search and replace "arduino.h" with "Arduino.h"

This probably only breaks on linux machines

but it also looks like the have a different lcd controller HD44780?? certainly doesn't display correctly on my 20x0
Re: Add password/lock screen to firmware
March 06, 2019 10:10PM
Got the LCD to work well enough

This is only required for us without your "special" LCD

in pins.h

find
#define LCD0 63
#define LCD1 40
#define LCD2 59
#define LCD3 64
#define LCD4 44
#define LCD5 66
#define LCD6 23
#define LCD7 25
#define LCD8 27
#define LCD9 29
#define LCDA 42
#define LCDB 65
#define LCDC 16
#define LCDD 17

replace with

#define LCD_PINS_RS 16
#define LCD_PINS_ENABLE 17
#define LCD_PINS_D4 23
#define LCD_PINS_D5 25
#define LCD_PINS_D6 27
#define LCD_PINS_D7 29

in ultralcd_implementation_hitachi_HD44780.h

find
LCD lcd(LCDC, LCDD, LCD2, LCD3, LCD4, LCD5, LCD6, LCD7, LCD8, LCD9);
replace with
LCD lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5,LCD_PINS_D6,LCD_PINS_D7);

now can start the combination lock code.....

Edited 1 time(s). Last edit at 03/06/2019 10:10PM by Dust.
Re: Add password/lock screen to firmware
March 07, 2019 02:32AM
yea, pretty difficult goal for me, but when the boss says get it done, I'm not really in a position to say no haha..
That's an amazing idea, yea just a combination code lock would work great.

I'm still trying to figure out how to communicate with the LCD lol... since it's "special" with so many pins, many of the online examples don't work.
Would love to see your implementation when you've done it!
Re: Add password/lock screen to firmware
March 07, 2019 03:12AM
Its taken me way longer than it should... fighting with marlin. But this is working for me. I went with 4 numbers.

NB the encoder reading is a bit twitchie, best rotate slow till you get the feel for it.

If you enter the wrong code it just goes back to the first box and starts prompting again.

Numbers are from 0-55 due to the way the math works out, still that is a fair few combinations

NB this line is important uint8_t combination[4] = {5,4,3,2};
it is the password. Don't forget it, no way to reset it (other than uploading new firmware) change it to what ever you want


changes:
add to ultralcd_implementation_hitachi_HD44780.h
static void lcd_lockscreen() {
    uint8_t entercode[4] = {0};
    uint8_t combination[4] = {5,4,3,2};
    bool lockstate = true;
    lcd.clear();
    //                                      "01234567890123456789"
    lcd.setCursor(0, 1); lcd_printPGM(PSTR( " Enter Combination. " ));
    lcd.setCursor(0, 3); lcd_printPGM(PSTR( "  [  ][  ][  ][  ]  " ));

    encoderDiff=0;

    while (lockstate) {
      for (int i = 0; i < 4; i++) { 
        while(digitalRead(BTN_ENC) == HIGH) {
          entercode[ i ] = encoderDiff/4; 
          lcd.setCursor(3+i*4, 3); lcd.print(itostr2(entercode[ i ]));
        }
        while(digitalRead(BTN_ENC) == LOW) {}
        lcd.setCursor(3+i*4, 3); lcd_printPGM(PSTR("XX"));
      }

      if ((entercode[0] == combination[0]) && (entercode[1] == combination[1]) && (entercode[2] == combination[2]) && (entercode[3] == combination[3])) 
      { 
        lockstate = false;
      }
    }

    buttons = 0;
    encoderDiff = 0;
 }
Add it above the line "static void lcd_implementation_status_screen()"

add to ultralcd.h
  void lcd_lockscreen();
Added above the line " #define LCD_MESSAGE_CPGM(x) lcd_setstatus_PGM(PSTR(x))"

add to Marlin_main.cpp
  lcd_lockscreen();
Add below the line " _delay_ms(1000); // wait 1sec to display the splash screen"


NB This shouldn't interfere with normal printing etc, but I can't test that. My test machine is just a 2004 LCD and a RAMPS (and a resistor to fool the controller that the temp probe is working.)

Edited 10 time(s). Last edit at 03/07/2019 05:07AM by Dust.
Re: Add password/lock screen to firmware
March 07, 2019 09:01PM
Freaking amazing, you're the man.

I'm wondering if you could explain the code a bit so I can learn?
Here's how i understand the code
static void lcd_lockscreen() { //state a function
    uint8_t entercode[4] = {0};  //variable to hold user input, a 4 item array, uint8_t instead of int to save memory i assume?
    uint8_t combination[4] = {5,4,3,2}; //variable holding password array
    bool lockstate = true;  //boolean to toggle the while loop/lock screen
    lcd.clear();  //clears the LCD
    //                                      "01234567890123456789"   //<--commenting to remind numbers only?
    lcd.setCursor(0, 1); lcd_printPGM(PSTR( " Enter Combination. " ));  //prints message on screen
    lcd.setCursor(0, 3); lcd_printPGM(PSTR( "  [  ][  ][  ][  ]  " ));  //printPGM(PSTR( and print(F the same thing? to save memory?

    encoderDiff=0;  //resets encoder value, how'd you know what the encoder variable is called? and why does it have to be reset? I took it out as a test and there doesn't seem to be any difference?

    while (lockstate) { //enters lock screen
      for (int i = 0; i < 4; i++) {   //loops thru the 4 array items
        while(digitalRead(BTN_ENC) == HIGH) {  //button function of encoder, a digital input, normally high when not pressed
          entercode[ i ] = encoderDiff/4;   //divide by 4 because encoder skips in increments of 4? 
          lcd.setCursor(3+i*4, 3); lcd.print(itostr2(entercode[ i ]));  //displays value, question: what's print(itostr2, why not just print or print(F?
        }
        while(digitalRead(BTN_ENC) == LOW) {}  //encoder button becomes low when pressed
        lcd.setCursor(3+i*4, 3); lcd_printPGM(PSTR("XX"));  //hides input value by printing XX, also lets user know a value was inputted
      }

      if ((entercode[0] == combination[0]) && (entercode[1] == combination[1]) && (entercode[2] == combination[2]) && (entercode[3] == combination[3]))  //when the entered and set passcode matches
      { 
        lockstate = false;  //sets boolean false to exit the loop/lock screen
      }
    }

    buttons = 0;  //what is this? the variable was never used, left over code?
    encoderDiff = 0;  //why do we have to reset the encoder value? does it affect anything if we just leave it?
 }

I've added
      lcd.setCursor(0, 2); lcd_printPGM(PSTR( "CODE WRONG TRY AGAIN" ));
      lcd.setCursor(0, 3); lcd_printPGM(PSTR( "  [  ][  ][  ][  ]  " ));
just after the IF function so it's fool proof and the user knows the code is wrong, and it clears the XX

55^4 is already secure enough for me, but i'm just curious: for the "Numbers are from 0-55 due to the way the math works out", is it because of the values the encoder outputs? (ie from: 0-220 in increments of 4),

are the spaces at the end of each print there just so it's easier to count the 20 character limit? or is there some other reason?

also, when I compile, it compiles fine, but there's some red text saying
In file included from sketch\ultralcd.cpp:40:0:

sketch\ultralcd_implementation_hitachi_HD44780.h: In function 'void lcd_lockscreen()':

sketch\ultralcd_implementation_hitachi_HD44780.h:433:28: warning: 'void lcd_lockscreen()' was declared 'extern' and later 'static' [-fpermissive]

 static void lcd_lockscreen() {

                            ^

In file included from sketch\ultralcd.cpp:2:0:

sketch\ultralcd.h:23:8: note: previous declaration of 'void lcd_lockscreen()'

   void lcd_lockscreen();

        ^
should i be concerned? I'm not really sure what it's saying? i think it's saying that
1.a function type is different from the type we stated? (but it still works?)
2. void lcd_lockscreen() is declared twice?

Thanks for the amazing work, so far everything works fine, I'll update if something acts weird.

Side note: If i want the lock screen to pop up when user tries to access the SD card instead (so that user can still load and unload filament...etc without being bothered by the lock screen), where would i put lcd_lockscreen();?
I tried to put it in
void loop()
just before line 602
#ifdef SDSUPPORT
if (card.saving)
and it's not the right place, the lock screen pops up after I've selected a file in the SD card, and the lockscreen loops itself.
any recommendations as to where to put it so it's initialized before entering the SD card?

Edited 2 time(s). Last edit at 03/07/2019 10:00PM by evo85210.
Re: Add password/lock screen to firmware
March 07, 2019 10:44PM
" // "01234567890123456789" //<--commenting to remind numbers only?"

comment for screen positioning, 20 char display

" encoderDiff=0; //resets encoder value, how'd you know what the encoder variable is called? and why does it have to be reset? I took it out as a test and there doesn't seem to be any difference?"

you reset it in case someone is already fiddling with the encoder before you ready for it. I dug threw marlin code to find this variable

" entercode[ i ] = encoderDiff/4; //divide by 4 because encoder skips in increments of 4? "
yes exactly.

" lcd.setCursor(3+i*4, 3); lcd.print(itostr2(entercode[ i ])); //displays value, question: what's print(itostr2, why not just print or print(F?"
forces the intger into a 2 character string, so for eg so 0 is 00

"while(digitalRead(BTN_ENC) == LOW) {} //encoder button becomes low when pressed"
wait for button to become not pressed, or it just selects all boxes not just the active box

"" buttons = 0; //what is this? the variable was never used, left over code?"
When you press the encode butten a Interrupt service routine in marlin stores that you press a button. Without this when you exit the lock screen it acts like you pressed a button a jumps away from the status screen

" encoderDiff = 0; //why do we have to reset the encoder value? does it affect anything if we just leave it?"
Same as above, encoder moves are stored in ISR, if you don't clear this then the current encoder offset get added to the FR on the main status screen on exit from the lock screen, changing the feed rate of the printer.

"55^4 is already secure enough for me, but i'm just curious: for the "Numbers are from 0-55 due to the way the math works out", is it because of the values the encoder outputs? (ie from: 0-220 in increments of 4),"
Yes it has vales from 0-220 in increments of 4.. would have to dig into the ISR to find out why...

"are the spaces at the end of each print there just so it's easier to count the 20 character limit? or is there some other reason?"

Yes so what you see on the code screen matches the lcd screen.


I don't get those warnings... you can remove the static keyword. Should fix it.


re sdcard... you would have to manipulate the menus inside marlin so that when the card menus is selected they get the lock screen first...
Some where inside lcd_sdcard_menu() in ultralcd.cpp I would guess. But the menu system very much eludes me so far.

Edited 1 time(s). Last edit at 03/07/2019 10:45PM by Dust.
Re: Add password/lock screen to firmware
March 12, 2019 02:38AM
Thanks for the explanation!
I've been playing with the marlin code a bit, trying to figure out how to implement the lock screen just before entering entering the SD card menu.
but for whatever reason, the lock screen would just loop itself.
lock screen on boot is working, so I think i'll shelf the SD card menu thought and just leave this as is for now.
If someone comes along and figures out how to implement it before the SD card menu, lease do let me know, thanks.
Re: Add password/lock screen to firmware
April 14, 2019 11:36PM
Hi dust, after extensive usage, we've noticed a small bug, when one of the values are set too high, the lock screen becomes unlock-able
ie: if the password is set to 00-00-00-40, it'll not unlock when the code in entered correctly.
I haven't found found the exact value that triggers this bug, but what we've noticed is that somewhere after the 30s, this bug will shows up.
Is there a debuging function I can use to figure out why? or can you take a look?
Currently we just split it if it goes over 30, ie 00-00-00-40 become 00-00-04-00
Re: Add password/lock screen to firmware
April 18, 2019 09:17AM
Luckily I still have the code....

I can confirm the issue... anything over 31 and it breaks....

looking deeper
Re: Add password/lock screen to firmware
April 18, 2019 10:05AM
ok... not sure what is going on, but worked around it

add in the line after the line "entercode[ i ] = encoderDiff/4;"

if(entercode[ i ] > 223) entercode[ i ] = entercode[ i ] - 192;

Edited 1 time(s). Last edit at 04/18/2019 10:07AM by Dust.
Re: Add password/lock screen to firmware
April 18, 2019 10:34PM
thanks, mad props
Re: Add password/lock screen to firmware
May 28, 2019 05:36AM
SD Menu update:
So i've found time to work on the firmware stuff again, this time instead of inserting the lockscreen between the main and SD menu, I hid the sd menus, and added a unlock menu item, so that the sd menus will only appear after unlocking.
So far it's working and i don't see any problems.

First i defined a global variable "lock", set it to 1, added
if(lock==1){
  MENU_ITEM(function, "Unlock", lcd_lockscreen);
  }else{
just before #ifdef SDSUPPORT in ultralcd.cpp
this'll hide the SD menus, and only show and option called Unlock

then in the lockscreen code, add lock=0; when the codes match.

and lastly lock=1; inside card.printingHasFinished(); to relock the menu once the print is done.

and some other misc. code, like storing and putting back the the button and encoder values before and after the lockscreen..etc
Sorry, only registered users may post in this forum.

Click here to login