initial commit
This commit is contained in:
parent
983704249b
commit
5735cbabb8
262
PhotoStepper/PhotoStepper.ino
Normal file
262
PhotoStepper/PhotoStepper.ino
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* PhotoStepper © 2022 by Ronald Schaten is licensed under CC BY-NC 4.0.
|
||||||
|
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this project makes heavy use of the following libraries:
|
||||||
|
// - https://www.arduino.cc/reference/en/libraries/arduinomenu-library/
|
||||||
|
// - https://www.arduino.cc/reference/en/libraries/stepperdriver/
|
||||||
|
// - https://www.arduino.cc/reference/en/libraries/analogkeypad/
|
||||||
|
//
|
||||||
|
// this is still WIP, the menu is basically taken from example code.
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <AnalogKeypad.h>
|
||||||
|
#include <BasicStepperDriver.h>
|
||||||
|
#include <menu.h>
|
||||||
|
#include <menuIO/liquidCrystalOut.h>
|
||||||
|
#include <menuIO/serialIO.h>
|
||||||
|
#include <menuIO/stringIn.h>
|
||||||
|
#include <menuIO/chainStream.h>
|
||||||
|
|
||||||
|
//using namespace Menu;
|
||||||
|
|
||||||
|
// analog keypad
|
||||||
|
#define PIN_BUTTON 0
|
||||||
|
// 2x16 LCD
|
||||||
|
#define PIN_LCD_DB4 4
|
||||||
|
#define PIN_LCD_DB5 5
|
||||||
|
#define PIN_LCD_DB6 6
|
||||||
|
#define PIN_LCD_DB7 7
|
||||||
|
#define PIN_LCD_RS 8
|
||||||
|
#define PIN_LCD_EN 9
|
||||||
|
#define PIN_LCD_BL 10
|
||||||
|
// stepper motor
|
||||||
|
#define PIN_STEPPER_DIR 2
|
||||||
|
#define PIN_STEPPER_STEP 3
|
||||||
|
// on-board led
|
||||||
|
#define PIN_LED 13
|
||||||
|
|
||||||
|
// motor configuration
|
||||||
|
#define STEPPER_STEPS 200
|
||||||
|
#define STEPPER_RPM 120
|
||||||
|
#define STEPPER_MICROSTEPS 1
|
||||||
|
#define STEPPER_ACCEL 2000
|
||||||
|
#define STEPPER_DECEL 1000
|
||||||
|
|
||||||
|
#define MAX_DEPTH 2
|
||||||
|
|
||||||
|
const int KeypadMap[] = {0, 96, 250, 402, 636};
|
||||||
|
const uint16_t KeypadHoldTimeMs = 5000;
|
||||||
|
const uint8_t KeypadAnalogPin = PIN_BUTTON;
|
||||||
|
AnalogKeypad keypad(KeypadAnalogPin, KeypadMap, countof(KeypadMap), KeypadHoldTimeMs);
|
||||||
|
|
||||||
|
LiquidCrystal lcd(PIN_LCD_RS, PIN_LCD_EN, PIN_LCD_DB4, PIN_LCD_DB5, PIN_LCD_DB6, PIN_LCD_DB7);
|
||||||
|
|
||||||
|
BasicStepperDriver stepper(STEPPER_STEPS, PIN_STEPPER_DIR, PIN_STEPPER_STEP);
|
||||||
|
|
||||||
|
// ===
|
||||||
|
|
||||||
|
result doAlert(eventMask e, prompt &item);
|
||||||
|
|
||||||
|
result showEvent(eventMask e) {
|
||||||
|
Serial.print("event: ");
|
||||||
|
Serial.println(e);
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test=55;
|
||||||
|
|
||||||
|
result action1(eventMask e,navNode& nav, prompt &item) {
|
||||||
|
Serial.print("action1 event:");
|
||||||
|
Serial.println(e);
|
||||||
|
Serial.flush();
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
result action2(eventMask e) {
|
||||||
|
Serial.print("actikon2 event:");
|
||||||
|
Serial.println(e);
|
||||||
|
Serial.flush();
|
||||||
|
return quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ledCtrl=LOW;
|
||||||
|
|
||||||
|
result myLedOn() {
|
||||||
|
ledCtrl=HIGH;
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
result myLedOff() {
|
||||||
|
ledCtrl=LOW;
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,wrapStyle//,doExit,enterEvent,noStyle
|
||||||
|
,VALUE("On",HIGH,doNothing,noEvent)
|
||||||
|
,VALUE("Off",LOW,doNothing,noEvent)
|
||||||
|
);
|
||||||
|
|
||||||
|
int selTest=0;
|
||||||
|
SELECT(selTest,selMenu,"Select",doNothing,noEvent,wrapStyle
|
||||||
|
,VALUE("Zero",0,doNothing,noEvent)
|
||||||
|
,VALUE("One",1,doNothing,noEvent)
|
||||||
|
,VALUE("Two",2,doNothing,noEvent)
|
||||||
|
);
|
||||||
|
|
||||||
|
int chooseTest=-1;
|
||||||
|
CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,wrapStyle
|
||||||
|
,VALUE("First",1,doNothing,noEvent)
|
||||||
|
,VALUE("Second",2,doNothing,noEvent)
|
||||||
|
,VALUE("Third",3,doNothing,noEvent)
|
||||||
|
,VALUE("Last",-1,doNothing,noEvent)
|
||||||
|
);
|
||||||
|
|
||||||
|
//customizing a prompt look!
|
||||||
|
//by extending the prompt class
|
||||||
|
class altPrompt:public prompt {
|
||||||
|
public:
|
||||||
|
altPrompt(constMEM promptShadow& p):prompt(p) {}
|
||||||
|
Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
|
||||||
|
return out.printRaw(F("special prompt!"),len);;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MENU(subMenu,"Sub-Menu",doNothing,anyEvent,wrapStyle
|
||||||
|
,OP("Sub1",showEvent,enterEvent)
|
||||||
|
,OP("Sub2",showEvent,enterEvent)
|
||||||
|
,OP("Sub3",showEvent,enterEvent)
|
||||||
|
,altOP(altPrompt,"",showEvent,enterEvent)
|
||||||
|
,EXIT("<Back")
|
||||||
|
);
|
||||||
|
|
||||||
|
//constText* constMEM textFilter MEMMODE=" .0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTWXYZ";
|
||||||
|
//constText* constMEM textMask[] MEMMODE={textFilter};//this mask will repeat till the end of the field
|
||||||
|
//char name[]=" ";//<-- menu will edit this text
|
||||||
|
|
||||||
|
MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
|
||||||
|
,OP("Op1",action1,anyEvent)
|
||||||
|
,OP("Op2",action2,enterEvent)
|
||||||
|
//,EDIT("Name",name,textMask,doNothing,noEvent,noStyle)
|
||||||
|
//,SUBMENU(togOp)
|
||||||
|
,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
|
||||||
|
,SUBMENU(subMenu)
|
||||||
|
,SUBMENU(setLed)
|
||||||
|
,OP("LED On",myLedOn,enterEvent)
|
||||||
|
,OP("LED Off",myLedOff,enterEvent)
|
||||||
|
,SUBMENU(selMenu)
|
||||||
|
,SUBMENU(chooseMenu)
|
||||||
|
,OP("Alert test",doAlert,enterEvent)
|
||||||
|
,EXIT("<Back")
|
||||||
|
);
|
||||||
|
|
||||||
|
MENU_OUTPUTS(out,MAX_DEPTH
|
||||||
|
,LIQUIDCRYSTAL_OUT(lcd,{0,0,16,2})
|
||||||
|
,NONE//must have 2 items at least
|
||||||
|
);
|
||||||
|
|
||||||
|
stringIn<0> strIn;//buffer size: 2^5 = 32 bytes, eventually use 0 for a single byte
|
||||||
|
serialIn serial(Serial);
|
||||||
|
// use this commented lines if you want your stringIn object to be used as part or normal menu input
|
||||||
|
// menuIn* inputsList[]={&serial,&strIn};
|
||||||
|
// chainStream<sizeof(inputsList)> in(inputsList);
|
||||||
|
// NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
|
||||||
|
NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
|
||||||
|
|
||||||
|
result alert(menuOut& o,idleEvent e) {
|
||||||
|
if (e==idling) {
|
||||||
|
o.setCursor(0,0);
|
||||||
|
o.print("alert test");
|
||||||
|
o.setCursor(0,1);
|
||||||
|
o.print("[select] to continue...");
|
||||||
|
Serial.println("rotating...");
|
||||||
|
stepper.startRotate(360);
|
||||||
|
}
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
result doAlert(eventMask e, prompt &item) {
|
||||||
|
nav.idleOn(alert);
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
result idle(menuOut& o,idleEvent e) {
|
||||||
|
switch(e) {
|
||||||
|
case idleStart:o.print("suspending menu!");break;
|
||||||
|
case idling:o.print("suspended...");break;
|
||||||
|
case idleEnd:o.print("resuming menu.");break;
|
||||||
|
}
|
||||||
|
return proceed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===
|
||||||
|
|
||||||
|
void ButtonHandler(const ButtonParam& param)
|
||||||
|
{
|
||||||
|
Serial.print(param.button);
|
||||||
|
Serial.print(" ");
|
||||||
|
switch (param.state) {
|
||||||
|
case ButtonState_Up:
|
||||||
|
Serial.print("Up");
|
||||||
|
break;
|
||||||
|
case ButtonState_Down:
|
||||||
|
Serial.print("Down");
|
||||||
|
break;
|
||||||
|
case ButtonState_Click:
|
||||||
|
Serial.print("Click");
|
||||||
|
switch (param.button) {
|
||||||
|
case 0: // right
|
||||||
|
break;
|
||||||
|
case 1: // up
|
||||||
|
nav.doNav(upCmd);
|
||||||
|
break;
|
||||||
|
case 2: // down
|
||||||
|
nav.doNav(downCmd);
|
||||||
|
break;
|
||||||
|
case 3: // left
|
||||||
|
break;
|
||||||
|
case 4: // select
|
||||||
|
nav.doNav(enterCmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nav.doOutput();
|
||||||
|
break;
|
||||||
|
case ButtonState_DoubleClick:
|
||||||
|
Serial.print("Double Click");
|
||||||
|
break;
|
||||||
|
case ButtonState_Hold:
|
||||||
|
Serial.print("Hold");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while(!Serial);
|
||||||
|
Serial.println("PhotoStepper -- schatenseite.de");
|
||||||
|
|
||||||
|
pinMode(PIN_LED, OUTPUT);
|
||||||
|
|
||||||
|
// control backlight
|
||||||
|
pinMode(PIN_LCD_BL, OUTPUT);
|
||||||
|
digitalWrite(PIN_LCD_BL, HIGH);
|
||||||
|
|
||||||
|
nav.idleTask=idle;//point a function to be used when menu is suspended
|
||||||
|
|
||||||
|
stepper.begin(STEPPER_RPM, STEPPER_MICROSTEPS);
|
||||||
|
stepper.setSpeedProfile(stepper.LINEAR_SPEED, STEPPER_ACCEL, STEPPER_DECEL);
|
||||||
|
|
||||||
|
lcd.begin(16,2);
|
||||||
|
lcd.setCursor(0, 0);
|
||||||
|
lcd.print("PhotoStepper");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.print("schatenseite.de");
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
keypad.loop(ButtonHandler);
|
||||||
|
stepper.nextAction();
|
||||||
|
digitalWrite(PIN_LED, ledCtrl);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user