Documentation Home
We will need one plastic case with follow dimension :axbxc
It is good decision to use one electrical junction box.
We will need 5x Optocuppler for 4x digital outout (L1, L2, L3, L4) and one for optical rotation detection digital input.
Depend of function Optocuppler must have right orientation (input parts have LED in circuite).
One 20×4 (2004) character LED display will be used to show information, and 5x tactile switchs (2 gray Up/Down, 1 black 1x/10x/100x, 1 red Stop and 1 green Start).
To connect all together it will be use LCD & Keyboard Adapter Board which use 7 digital I/O line for communication with LCD Display and 1 analogue line for connection with 5 keys.
LSP (low speed) - from 0 to HSP (default 0Hz)
HSP (high speed) - from LSP to 200Hz (default 50/60Hz)
When 3C is set LSP is final working speed predefined via configuration or set via resistor on analog input.
Ramp and Ramp2 is predefined in seconds which will take from begining speed till final speed.
Image of logical sinalisation:
L1 Stop
L2 Run/Forward
L3 Speed2
L4 Second Ramp
tCC → ACt → 3C
rrS → n0
PS2 → LIA → LI3
PS2 → LIb → n0
PS2 → SP2 → 25
rP2 → LI → LI4
Any key press for final screen.
/*
Author: Dubravko Penezic
Version: 1.0, 2012
This code is for controling Altivar 11 unit, and counting rotation.
Source code is provided as is, without any warranty.
Distributetd under CC BY v 3.0
http://pcb.daince.net/doku.php?id=arduino_code
*/
/*
include class for formating numbers to string
*/
#include <DpFormatNumber.h>
//initialize class
DpFormatNumber fN;
//7 chars for transforming number to string
char cs[7];
/*
include class for LCD display settings
*/
#include <LiquidCrystal.h>
// LCD digital I/O pins
int BeLi_LCD_pin = 9;
int RS_LCD_pin = 7;
int En_LCD_pin = 8;
int D4_LCD_pin = 13;
int D5_LCD_pin = 12;
int D6_LCD_pin = 11;
int D7_LCD_pin = 10;
// initialize class with interface pins information
LiquidCrystal lcd(RS_LCD_pin, En_LCD_pin, D4_LCD_pin, D5_LCD_pin, D6_LCD_pin, D7_LCD_pin);
/*
include class for showing large 4 row numbers
*/
#include <DpLCDBigNumber4L.h>
// initialize class with pointer to LCD class
DpLCDBigNumber4L lcdn(&lcd);
/*
keyboard settings
*/
//Analogue value for key
int adc_key_val[6] ={30, 170, 390, 570, 790, 1024 };
//Key function
int key_fun[6] = {3, //Count up
2, //Count down
4, //10x, reset
0, //Start
1 //Stop
};
//Number of keys
int NUM_KEYS = 6;
//Analog pin
int aKeyPin = 7;
//last key value
int key = 5;
/*
digital output settings
*/
// {pin,LOW|HIGH}
int Lx[4][2] = {
{6,LOW}, // L1 - Stop
{5,LOW}, // L2 - Forward
{3,LOW}, // L3 - Speed 2
{4,LOW} // L4 - Ramp2
};
/*
digital input settings
*/
//Digital pin
int od = 2;
/*
configuration variable for program execution
*/
//pre set counter
long counter = 0;
//counted ticks
long actCounter = 0;
//counting ticks or not
int start_count = 0;
// time in miliseconds waiting for another digit when setting counter
int sCd = 100;
// time in seconds before actualy start motor
int pSt = 15;
//ramp delay time
int Ramp1DT = 3000;
int Ramp2DT = 5000;
//Counter diff mark to stop
long stopDiff = 10;
//Counter diff mark to stop speed 2
long stopSP2Diff = 50;
// work type - 0 setting counter
// 1 counting and controling electro motore
int work_type = 0;
// setup
void setup(void) {
//set output digital pins to OUTPUT state
for (int i = 0; i < 4; i++) {
pinMode(Lx[i][0], OUTPUT);
}
//set all digital input pins to LOW
allLxLow();
//set interupt procdure countRotation to interupt 0 and using RISING parameter
attachInterrupt(0, countRotation, RISING);
// start serial port
Serial.begin(9600);
Serial.println("CounterAltivar11 v 1.0");
Serial.println("Author: Dubravko Penezic, 2013");
Serial.println("CC BY v 3.0");
//set becklite on LCD on
pinMode(BeLi_LCD_pin, OUTPUT);
digitalWrite(BeLi_LCD_pin, HIGH);
//set LCD parameters
lcd.begin(40, 2);
lcd.noCursor();
lcd.clear();
//set big number graphems
lcdn.setGC();
//show welcome message
showStartMessage();
}
//main loop
void loop(void) {
// set counter
if(work_type == 0) setCounter();
// counting
if(work_type == 1) doJob();
}
// interrupt handling
void countRotation() {
if(start_count == 1) actCounter++;
}
/*
setting counter procedures
*/
void setCounter() {
int cv = 1;
showCounter(counter);
while(work_type == 0) {
key = readKeyPad();
if(key == key_fun[0]) counter=counter+cv;
if(key == key_fun[1]) counter=counter-cv;
if(key == key_fun[4]) counter=0;
if(key == key_fun[2] && cv == 1) cv=10;
else if (key == key_fun[2] && cv == 10) cv=100;
else if (key == key_fun[2] && cv == 100) cv = 1;
if(key == key_fun[3]) work_type = 1;
if(key != 5) {
showCounter(counter);
}
delay(sCd);
}
}
/*
couting rotattion and manage motor action
*/
void doJob(){
int finStat = 0;
actCounter = 0;
waitToStart();
if(work_type == 0) finStat = 1;
else {
lcd.clear();
showCounter(counter-actCounter);
start_count=1;
LxStart();
}
while(work_type == 1){
showCounter(counter-actCounter);
key = readKeyPad();
if(key == key_fun[4]){
LxStop();
finStat = 2;
work_type = 0;
}
if(key == key_fun[0])
LxStartSP2();
if(key == key_fun[1])
LxStopSP2();
if((counter-actCounter)<stopSP2Diff && work_type == 1)
LxStopSP2();
if((counter-actCounter)<stopDiff && work_type == 1) {
LxStop();
work_type = 0;
}
}
start_count=0;
waitOnEnd(finStat, actCounter);
}
//set all Lx input to low
void allLxLow() {
for (int i = 0; i < 4; i++)
setLx(i,LOW);
}
//set Lx input
void setLx(int pos, int val) {
digitalWrite(Lx[pos][0], val);
Lx[pos][1] = val;
}
//job start sequence
void LxStart() {
Serial.println("Start speed");
int dt = 1000;
if(Lx[0][1] == 1)
dt = 20000;
allLxLow();
delay(dt);
setLx(0,HIGH);
delay(1000);
setLx(1,HIGH);
delay(Ramp1DT);
setLx(3,HIGH);
delay(Ramp2DT);
setLx(3,LOW);
delay(500);
setLx(1,LOW);
}
//job stop sequence
void LxStop(){
Serial.println("Stop speed");
if(Lx[0][1] == 1) {
setLx(3,HIGH);
delay(500);
setLx(0,LOW);
delay(Ramp2DT);
setLx(3,LOW);
delay(Ramp1DT);
}
allLxLow();
}
//job start Speed 2 sequence
void LxStartSP2() {
Serial.println("Start Speed 2");
if(Lx[2][1] == 0) {
setLx(2,HIGH);
delay(Ramp1DT);
setLx(3,HIGH);
delay(Ramp2DT);
setLx(3,LOW);
}
}
//job stop Speed 2 sequence
void LxStopSP2() {
Serial.println("Stop Speed 2");
if(Lx[2][1] == 1) {
setLx(3,HIGH);
delay(500);
setLx(2,LOW);
delay(Ramp2DT);
setLx(3,LOW);
delay(Ramp1DT);
}
}
//job preparing sequence
void waitToStart() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Seconds");
lcd.setCursor(0, 1);
lcd.print("Till");
lcd.setCursor(20, 0);
lcd.print("Start");
int i = pSt;
while( work_type ==1 && i >= 0) {
fN.UnsInt2ForStr(i,4,true,cs);
lcdn.printStrNo(cs,8);
key = readKeyPad();
if(key == key_fun[4]) work_type = 0;
delay(1000);
i--;
}
}
//job finishing sequence
void waitOnEnd(int finStat, long actCounter) {
String pSt;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Current job done");
lcd.setCursor(20, 0);
lcd.print("Job status:");
lcd.setCursor(32, 0);
if(finStat == 0) lcd.print(" OK ");
else if (finStat == 1) lcd.print("USER brk");
else if (finStat == 2) lcd.print("WORK brk");
pressAnyKey();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Counter set :");
fN.SigLon2ForStr(counter,6,true,cs);
lcd.setCursor(15, 0);
lcd.print(cs);
lcd.setCursor(0, 1);
lcd.print("Counter mess:");
fN.SigLon2ForStr(actCounter,6,true,cs);
lcd.setCursor(15, 1);
lcd.print(cs);
lcd.setCursor(20, 1);
lcd.print("Counter diff:");
fN.SigLon2ForStr(counter-actCounter,6,true,cs);
lcd.setCursor(35, 1);
lcd.print(cs);
pressAnyKey();
}
/*
presentation procedure
*/
void showCounter(long counter_tmp) {
if(counter_tmp<0) fN.SigLon2ForStr(counter_tmp,7,true,cs);
else fN.SigLon2ForStr(counter_tmp,6,true,cs);
lcdn.printStrNo(cs,0);
}
void showStartMessage(){
lcd.setCursor(0, 0);
lcd.print("Altivar Counter v1.0");
lcd.setCursor(0, 1);
lcd.print(" 2013 ");
lcd.setCursor(20, 0);
lcd.print("Author:");
lcd.setCursor(20, 1);
lcd.print("Dubravko Penezic");
delay(5000);
lcd.clear();
}
/*
working with keys
*/
//read key
int readKeyPad() {
int adc_key_in;
int key_begin;
int key_end;
adc_key_in = analogRead(aKeyPin); // read the value from the sensor
key_begin = get_key(adc_key_in); // convert into key press
delay(50); // wait for debounce time
adc_key_in = analogRead(aKeyPin); // read the value from the sensor
key_end = get_key(adc_key_in); // convert into key press
if(key_begin != key_end) return 5; // some error, nothing is press
else return key_begin;
}
// Convert ADC value to key number
int get_key(unsigned int input) {
int k;
for (k = 0; k < NUM_KEYS; k++) {
if (input < adc_key_val[k]) {
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}
//waiting for key to be press
void pressAnyKey() {
delay(5000);
key = readKeyPad();
while(key == 5){
key = readKeyPad();
delay(sCd);
}
}
/*
Author: Dubravko Penezic
Version: 1.0, 2012
This code is for controling Altivar 11 unit, and counting rotation.
Source code is provided as is, without any warranty.
Distributetd under CC BY v 3.0
http://pcb.daince.net/doku.php?id=arduino_code
*/
/*
include class for formating numbers to string
*/
#include <DpFormatNumber.h>
//initialize class
DpFormatNumber fN;
//7 chars for transforming number to string
char cs[7];
/*
include class for LCD display settings
*/
#include <LiquidCrystal.h>
// LCD digital I/O pins
int BeLi_LCD_pin = 9;
int RS_LCD_pin = 7;
int En_LCD_pin = 8;
int D4_LCD_pin = 13;
int D5_LCD_pin = 12;
int D6_LCD_pin = 11;
int D7_LCD_pin = 10;
// initialize class with interface pins information
LiquidCrystal lcd(RS_LCD_pin, En_LCD_pin, D4_LCD_pin, D5_LCD_pin, D6_LCD_pin, D7_LCD_pin);
/*
include class for showing large 4 row numbers
*/
#include <DpLCDBigNumber4L.h>
// initialize class with pointer to LCD class
DpLCDBigNumber4L lcdn(&lcd);
/*
keyboard settings
*/
//Analogue value for key
int adc_key_val[6] ={30, 170, 390, 570, 790, 1024 };
//Key function
int key_fun[6] = {3, //Count up
2, //Count down
4, //10x, reset
0, //Start
1 //Stop
};
//Number of keys
int NUM_KEYS = 6;
//Analog pin
int aKeyPin = 7;
//last key value
int key = 5;
/*
digital output settings
*/
// {pin,LOW|HIGH}
int Lx[4][2] = {
{6,LOW}, // L1 - Forvard
{5,LOW}, // L2 - Revers
{3,LOW}, // L3 - Speed 2
{4,LOW} // L4 - Revers
};
/*
digital input settings
*/
//Digital pin
int od = 2;
/*
configuration variable for program execution
*/
//pre set counter
long counter = 0;
//counted ticks
long actCounter = 0;
//counting ticks or not
int start_count = 0;
// time in miliseconds waiting for another digit when setting counter
int sCd = 50;
// time in seconds before actualy start motor
int pSt = 2;
//ramp delay time
int Ramp1DT = 3000;
int Ramp2DT = 5000;
//Counter diff mark to stop
long stopDiff = 2;
//Counter diff mark to stop speed 2
long stopSP2Diff = 10;
// work type - 0 setting counter
// 1 counting and controling electro motore
int work_type = 0;
int reverse=1;
// setup
void setup(void) {
//set output digital pins to OUTPUT state
for (int i = 0; i < 4; i++) {
pinMode(Lx[i][0], OUTPUT);
}
//set all digital input pins to LOW
allLxLow();
//set interupt procdure countRotation to interupt 0 and using RISING parameter
attachInterrupt(0, countRotation, RISING);
// start serial port
Serial.begin(9600);
Serial.println("CounterAltivar11 v 1.0");
Serial.println("Author: Dubravko Penezic, 2013");
Serial.println("CC BY v 3.0");
//set becklite on LCD on
pinMode(BeLi_LCD_pin, OUTPUT);
digitalWrite(BeLi_LCD_pin, HIGH);
//set LCD parameters
lcd.begin(40, 2);
lcd.noCursor();
lcd.clear();
//set big number graphems
lcdn.setGC();
//show welcome message
showStartMessage();
}
//main loop
void loop(void) {
// set counter
if(work_type == 0) setCounter();
// counting
if(work_type == 1) doJob();
}
// interrupt handling
void countRotation() {
if(start_count == 1) actCounter++;
}
/*
setting counter procedures
*/
void setCounter() {
int cv = 1;
showCounter(counter);
while(work_type == 0) {
key = readKeyPad();
if(key == key_fun[0]) counter=counter+cv;
if(key == key_fun[1]) counter=counter-cv;
if(key == key_fun[4]) {
delay(3000);
key = readKeyPad();
if(key == key_fun[4])
counter=0;
}
if(key == key_fun[2] && cv == 1) cv=10;
else if (key == key_fun[2] && cv == 10) cv=100;
else if (key == key_fun[2] && cv == 100) cv = 1;
if(key == key_fun[3]) work_type = 1;
if(key != 5) {
showCounter(counter);
}
delay(sCd);
}
}
/*
couting rotattion and manage motor action
*/
void doJob(){
int finStat = 0;
actCounter = 0;
waitToStart();
if(counter<0)
reverse = -1;
else
reverse = 1;
if(work_type == 0) finStat = 1;
else {
lcd.clear();
showCounter(counter-actCounter);
start_count=1;
LxStart();
}
while(work_type == 1){
// showCounter(counter-actCounter);
showCounter(actCounter);
key = readKeyPad();
if(key == key_fun[2]) {
LxStop();
reverse = reverse * -1;
delay(1000);
LxStart();
}
if(key == key_fun[4]){
LxStop();
finStat = 2;
work_type = 0;
}
if(key == key_fun[0])
LxStartSP2();
if(key == key_fun[1])
LxStopSP2();
if(((counter*reverse)-actCounter)<stopSP2Diff && work_type == 1)
LxStopSP2();
if(((counter*reverse)-actCounter)<stopDiff && work_type == 1) {
LxStop();
work_type = 0;
}
}
start_count=0;
waitOnEnd(finStat, actCounter);
}
//set all Lx input to low
void allLxLow() {
for (int i = 0; i < 4; i++)
setLx(i,LOW);
}
//set Lx input
void setLx(int pos, int val) {
digitalWrite(Lx[pos][0], val);
Lx[pos][1] = val;
}
//job start sequence
void LxStart() {
Serial.println("Start speed");
allLxLow();
delay(500);
if(reverse == 1)
setLx(0,HIGH);
else
setLx(1,HIGH);
}
//job stop sequence
void LxStop(){
Serial.println("Stop speed");
if(reverse == 1)
setLx(0,LOW);
else
setLx(1,LOW);
delay(Ramp1DT);
allLxLow();
}
//job start Speed 2 sequence
void LxStartSP2() {
Serial.println("Start Speed 2");
if(Lx[2][1] == 0) {
setLx(2,HIGH);
delay(Ramp1DT);
}
}
//job stop Speed 2 sequence
void LxStopSP2() {
Serial.println("Stop Speed 2");
if(Lx[2][1] == 1) {
setLx(2,LOW);
delay(Ramp1DT);
}
}
//job preparing sequence
void waitToStart() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Seconds");
lcd.setCursor(0, 1);
lcd.print("Till");
lcd.setCursor(20, 0);
lcd.print("Start");
int i = pSt;
while( work_type ==1 && i >= 0) {
fN.UnsInt2ForStr(i,4,true,cs);
lcdn.printStrNo(cs,8);
key = readKeyPad();
if(key == key_fun[4]) work_type = 0;
delay(1000);
i--;
}
}
//job finishing sequence
void waitOnEnd(int finStat, long actCounter) {
lcd.clear();
showCounter(actCounter);
delay(2000);
key=5;
pressAnyKey();
}
//job finishing sequence
void waitOnEnd1(int finStat, long actCounter) {
String pSt;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Current job done");
lcd.setCursor(20, 0);
lcd.print("Job status:");
lcd.setCursor(32, 0);
if(finStat == 0) lcd.print(" OK ");
else if (finStat == 1) lcd.print("USER brk");
else if (finStat == 2) lcd.print("WORK brk");
pressAnyKey();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Counter set :");
fN.SigLon2ForStr(counter,6,true,cs);
lcd.setCursor(15, 0);
lcd.print(cs);
lcd.setCursor(0, 1);
lcd.print("Counter mess:");
fN.SigLon2ForStr(actCounter,6,true,cs);
lcd.setCursor(15, 1);
lcd.print(cs);
lcd.setCursor(20, 1);
lcd.print("Counter diff:");
fN.SigLon2ForStr(counter-actCounter,6,true,cs);
lcd.setCursor(35, 1);
lcd.print(cs);
pressAnyKey();
}
/*
presentation procedure
*/
void showCounter(long counter_tmp) {
if(counter_tmp<0) fN.SigLon2ForStr(counter_tmp,7,true,cs);
else fN.SigLon2ForStr(counter_tmp,6,true,cs);
lcdn.printStrNo(cs,0);
}
void showStartMessage(){
lcd.setCursor(0, 0);
lcd.print("Altivar Counter v1.0");
lcd.setCursor(0, 1);
lcd.print(" 2013 ");
lcd.setCursor(20, 0);
lcd.print("Author:");
lcd.setCursor(20, 1);
lcd.print("Dubravko Penezic");
delay(5000);
lcd.clear();
}
/*
working with keys
*/
//read key
int readKeyPad() {
int adc_key_in;
int key_begin;
int key_end;
adc_key_in = analogRead(aKeyPin); // read the value from the sensor
key_begin = get_key(adc_key_in); // convert into key press
delay(50); // wait for debounce time
adc_key_in = analogRead(aKeyPin); // read the value from the sensor
key_end = get_key(adc_key_in); // convert into key press
if(key_begin != key_end) return 5; // some error, nothing is press
else return key_begin;
}
// Convert ADC value to key number
int get_key(unsigned int input) {
int k;
for (k = 0; k < NUM_KEYS; k++) {
if (input < adc_key_val[k]) {
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}
//waiting for key to be press
void pressAnyKey() {
delay(2000);
key = readKeyPad();
while(key == 5){
key = readKeyPad();
delay(sCd);
}
}
<file ino Counter_3.0.0.ino> /* Author: Dubravko Penezic Version: 1.0, 2012 This code is for counting rotation. Source code is provided as is, without any warranty. Distributetd under CC BY v 3.0 http://pcb.daince.net/doku.php?id=arduino_code */ Format numbers to string #include <DpFormatNumber.h> DpFormatNumber fN;
Display settings #include <LiquidCrystal.h> #include <DpLCDBigNumber4L.h> LCD pins int BeLi_LCD_pin = 9; int RS_LCD_pin = 7; int En_LCD_pin = 8; int D4_LCD_pin = 13; int D5_LCD_pin = 12; int D6_LCD_pin = 11; int D7_LCD_pin = 10;
initialize the library with the numbers of the interface pins LiquidCrystal lcd(RS_LCD_pin, En_LCD_pin, D4_LCD_pin, D5_LCD_pin, D6_LCD_pin, D7_LCD_pin); DpLCDBigNumber4L lcdn(&lcd); Switch settings Analogue value for key int adc_key_val[6] ={30, 170, 390, 570, 790, 1024 }; Key function int key_fun[6] = {3, Count up 2, Count down
4, //10x, reset
0, //Start
1 //Stop
};
Number of keys int NUM_KEYS = 6; Analog pin int aKeyPin = 7;
int key = 5;
Digital input int od = 2; work type - 0 setting counter 1 counting and controling electro motore int work_type = 0; int start_count = 0; counter volatile long actCounter = 0; boolean counting = false; char cs[7]; time in miliseconds waiting for another digiti when setting counter int sCd = 100; int Ramp2DT = 5000; void setup(void) { pinMode(BeLi_LCD_pin, OUTPUT); digitalWrite(BeLi_LCD_pin, HIGH); attachInterrupt(0, countRotation, RISING); start serial port
Serial.begin(9600);
Serial.println("Counter v 2.0");
lcd.begin(40, 2); lcd.noCursor(); lcd.clear(); showStartMessage(); lcdn.setGC();
}
void loop(void) {
showCounter(actCounter);
key = readKeyPad();
if(key == key_fun[4]){
actCounter = 0;
lcd.clear();
}
}
void countRotation() {
actCounter++;
}
void showCounter(long counter_tmp) {
if(counter_tmp<0) fN.SigLon2ForStr(counter_tmp,7,true,cs); else fN.SigLon2ForStr(counter_tmp,6,true,cs); lcdn.printStrNo(cs,0);
}
void showStartMessage(){
lcd.setCursor(0, 0);
lcd.print("Counter v1.0");
lcd.setCursor(0, 1);
lcd.print(" 2013 ");
lcd.setCursor(20, 0);
lcd.print("Author:");
lcd.setCursor(20, 1);
lcd.print("Dubravko Penezic");
delay(5000);
lcd.clear();
}
int readKeyPad() {
int adc_key_in; int key_begin; int key_end; adc_key_in = analogRead(aKeyPin); // read the value from the sensor key_begin = get_key(adc_key_in); // convert into key press delay(50); // wait for debounce time adc_key_in = analogRead(aKeyPin); // read the value from the sensor key_end = get_key(adc_key_in); // convert into key press
if(key_begin != key_end) return 5; some error, nothing is press else return key_begin; } Convert ADC value to key number int get_key(unsigned int input) {
int k;
for (k = 0; k < NUM_KEYS; k++) {
if (input < adc_key_val[k]) {
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k; } </file>
Parts and accessories cca 65 US$
Working time 8-10 hours cca 80 US$