I think I have an "int" vs. "char" problem, but not sure how to solve it. Here is the sketch for the project (a controller for a stepper motor to tune an antenna):
#pragma once
#include <Rotary.h>
#include <Arduino.h>
#include <EEPROM.h>
#include <Servo.h>
/*
* Example using the Rotary library, dumping integers to the serial
* port. The integers increment or decrement depending on the direction
* of rotation.
*
* This example uses interrupts rather than polling.
* From URL: http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
*/
#include <EEPROMWearLevel.h>
// Include Wire Library for I2C
# include <Wire.h>
// Include NewLiquidCrystal Library for I2C
# include <LiquidCrystal_I2C.h>
// NewLiquidCrystal.h
// Define LCD pinout
const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
// Define I2C Address - change if reqiuired
// const int i2c_addr = 0x27;
// LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);
//following added from web https://github.com/duinoWitchery/hd44780/wiki/ioClass:-hd44780_I2Cexp
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate i2c address & auto config expander chip pin mapping
#define EEPROM_LAYOUT_VERSION 1
#define AMOUNT_OF_INDEXES 1
#define INDEX_RING_BUFFER 0
// Rotary encoder is wired with the common to ground and the two
// outputs to pins 2 and 3.
Rotary rotary = rotary(2, 3);
enum PinAssignments {
encoderPinA = 2, // right
encoderPinB = 3, // left
clearButton = 5, // Encoder swtich
};
// Defines 20M location variables
int long TwentyM_Pos = 3248; // 3330 predefined travel distance to 40M from 20M
int long TwentyM_sw = 11; // 20M target select switch
// Defines 30M location variables
int long ThirtyM_Pos = 1953; // predefined travel distance to 40M from 30M
int long ThirtyM_sw = 10; // 30M target select switch
// Defines 40M location variables
int long FortyM_Pos = 0; // 3362 predefined travel distance to 40M from 20M
// defines pins numbers for motor driver A4988
const int stepPin = 8;
const int dirPin = 9;
// Counter that will be incremented or decremented by rotation.
long counter = 0;
long old_count = counter; // old_count tells lcd to update if different than counter
long value = counter; //largest value that might be written to EEPROM
long FortyM_start = 0; // Starting position for 40M
// defines power failure sensing
int DCdown = 6;
int PowerFail;
int unsaved = LOW;
void setup() {
/*
*On a brand new Arduino board, remove the comment on the following line of code, power up the board, then,
*power fail the board.
*Next, comment out the following line. This presets the counter stored value to a known location.
*counter = 0;
*/
// Sets power failure sense pin
pinMode(DCdown, INPUT_PULLUP);
// Sets the two pins as Outputs for stepper motor
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(clearButton, INPUT);
// turn on pullup resistors
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
digitalWrite(clearButton, HIGH);
digitalWrite(ThirtyM_sw, HIGH);
digitalWrite(TwentyM_sw, HIGH);
digitalWrite(DCdown, HIGH);
Serial.begin(115200);
while (!Serial);
attachInterrupt(0, rotate, CHANGE);
attachInterrupt(1, rotate, CHANGE);
EEPROMwl.begin(EEPROM_LAYOUT_VERSION, AMOUNT_OF_INDEXES);
readData(); //reads data stored in EEPROM to find last used counter value
// Set display type as 16 char, 2 rows
lcd.begin(16,2);
// Print on first row
lcd.setCursor(0,0);
lcd.print("Counter");
// Wait 0.1 second
delay(100);
// Print on second row
lcd.setCursor(0,1);
lcd.print(counter);
// Wait 0.1 seconds
delay(100);
}
void loop() {
if (old_count != counter) {
// Clear the display
lcd.clear();
// Print on first row
lcd.setCursor(0,0);
lcd.print("Counter");
// Wait 0.1 second
delay(100);
// Print on second row
lcd.setCursor(0,1);
lcd.print(counter);
// Wait 0.1 seconds
delay(100);
old_count = counter;
}
PowerFail = digitalRead ( DCdown );
if ( PowerFail == HIGH && unsaved == LOW) {
Serial.print("V7.0:Storing power failure: counter: ");
Serial.println(counter);
writeData(); // we only want to save to eeprom once when power fails
Serial.println("Line 176: counter");
Serial.println(counter);
unsaved = HIGH;
delay(750);
}
if ( PowerFail == LOW ) {
unsaved = LOW;
}
// *********** reset/40 Meters **********
/*
Sets counter to "0" which is lowest freq., 40M.
Upon power up, the tuning position is assumed to be 40M. Future
location stored in EEPROM and that position will be recalled upon boot up.
*/
if (digitalRead(clearButton) == LOW ) {
Serial.println("Line 197: counter");
Serial.println(counter);
while (counter < 0) {
CCW_direction();
}
while (counter > 0) {
CW_direction();
}
writeData();
readData();
}
// ************ 30 Meter switch handler: ************
if (digitalRead(ThirtyM_sw) == LOW ) {
Serial.println("Line 216: counter");
Serial.println(counter);
while (counter < ThirtyM_Pos) {
CCW_direction();
}
while (counter > ThirtyM_Pos) {
CW_direction();
}
writeData();
readData();
}
// ************ 20 Meter switch handler: ************
if (digitalRead(TwentyM_sw) == LOW ) {
Serial.println("Line 254: counter");
Serial.println(counter);
while (counter < TwentyM_Pos) {
CCW_direction();
}
while (counter > TwentyM_Pos) {
CW_direction();
}
writeData();
readData();
}
}
void writeData() {
// writes a new value no matter what value was written before.
EEPROMwl.putToNext(INDEX_RING_BUFFER, counter);
}
void readData() {
int dataLength = 4;
long currentIndex = EEPROMwl.getCurrentIndexEEPROM(INDEX_RING_BUFFER, dataLength);
Serial.print("251: EEPROM stored value: ");
Serial.println(EEPROM.get(currentIndex, value));
counter = (EEPROM.get(currentIndex, value));
int EEPROM_address = (currentIndex);
Serial.print("256: EEPROM_address:");
Serial.println(EEPROM_address);
}
void CCW_direction() {
digitalWrite(dirPin,HIGH); // Enables the motor to move in a CCW direction (higher frequency)
for(int long x = 0; x < 20; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(800);
digitalWrite(stepPin,LOW);
delayMicroseconds(800);
}
old_count = counter;
counter++;
Serial.print("Line 273 CCW: ");
Serial.println(counter);
// Clear the display
lcd.clear();
// Print on first row
lcd.setCursor(0,0);
lcd.print("Counter");
// Wait 0.1 second
// delay(100);
// Print on second row
lcd.setCursor(0,1);
lcd.print(counter);
// Wait 0.1 seconds
// delay(100);
old_count = counter;
}
void CW_direction(){
// Rotation requests for 20 pulse movement CW
digitalWrite(dirPin,LOW); // Enables the motor to move in a CW direction (lower frequency)
// Makes 20 pulses for making 1/10 cycle rotation
for(long int x = 0; x < 20; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(800);
digitalWrite(stepPin,LOW);
delayMicroseconds(800);
}
old_count = counter;
counter--;
Serial.print("Line 311 CW: ");
Serial.println(counter);
// Clear the display
lcd.clear();
// Print on first row
lcd.setCursor(0,0);
lcd.print("Counter");
// Wait 0.1 second
// delay(100);
// Print on second row
lcd.setCursor(0,1);
lcd.print(counter);
// Wait 0.1 seconds
// delay(100);
old_count = counter;
}
// rotate is called anytime the rotary inputs change state.
void rotate() {
unsigned char result = rotary.process();
if (result == DIR_CCW) {
counter++;
Serial.println(counter);
// Rotary encoder requests 20 pulse movement CCW
digitalWrite(dirPin,HIGH); // Enables the motor to move in a CCW direction (raises frequency)
// Makes 20 pulses for making 1/10 cycle rotation
for(int x = 0; x < 20; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(800);
digitalWrite(stepPin,LOW);
delayMicroseconds(800);
}
} else if (result == DIR_CW) {
counter--;
Serial.println(counter);
// Rotary encoder requests 20 pulse movement CW
digitalWrite(dirPin,LOW); // Enables the motor to move in a CW direction (lower frequency)
// Makes 20 pulses for making 1/10 cycle rotation
for(long int x = 0; x < 20; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(800);
digitalWrite(stepPin,LOW);
delayMicroseconds(800);
}
}
}
Here is the rotary.h file:
/*
* Rotary encoder library for Arduino.
*/
#ifndef Rotary_h
#define Rotary_h
#include "Arduino.h"
// Enable this to emit codes twice per step.
// #define HALF_STEP
// Values returned by 'process'
// No complete step yet.
#define DIR_NONE 0x0
// Clockwise step.
#define DIR_CW 0x10
// Counter-clockwise step.
#define DIR_CCW 0x20
class Rotary
{
public:
Rotary(char, char);
unsigned char process();
void begin(bool internalPullup=true, bool flipLogicForPulldown=false);
inline unsigned char pin_1() const { return pin1; }
inline unsigned char pin_2() const { return pin2; }
private:
unsigned char state;
unsigned char pin1;
unsigned char pin2;
unsigned char inverter;
};
#endif
Here is the rotary.cpp file:
/* Rotary encoder handler for arduino.
*
* Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
* Contact: bb@cactii.net
*
*/
#include "Arduino.h"
#include "Rotary.h"
/*
* The below state table has, for each state (row), the new state
* to set based on the next encoder output. From left to right in,
* the table, the encoder outputs are 00, 01, 10, 11, and the value
* in that position is the new state to set.
*/
#define R_START 0x0
#ifdef HALF_STEP
// Use the half-step state table (emits a code at 00 and 11)
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] = {
// R_START (00)
{R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START},
// R_CCW_BEGIN
{R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START},
// R_CW_BEGIN
{R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START},
// R_START_M (11)
{R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START},
// R_CW_BEGIN_M
{R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW},
// R_CCW_BEGIN_M
{R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW},
};
#else
// Use the full-step state table (emits a code at 00 only)
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6
const unsigned char ttable[7][4] = {
// R_START
{R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START},
// R_CW_FINAL
{R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW},
// R_CW_BEGIN
{R_CW_NEXT, R_CW_BEGIN, R_START, R_START},
// R_CW_NEXT
{R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START},
// R_CCW_BEGIN
{R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START},
// R_CCW_FINAL
{R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW},
// R_CCW_NEXT
{R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif
/*
* Constructor. Each arg is the pin number for each encoder contact.
*/
Rotary::Rotary(char _pin1, char _pin2) {
// Assign variables.
pin1 = _pin1;
pin2 = _pin2;
// Initialise state.
state = R_START;
// Don't invert read pin state by default
inverter = 0;
}
void Rotary::begin(bool internalPullup, bool flipLogicForPulldown) {
if (internalPullup){
// Enable weak pullups
pinMode(pin1,INPUT_PULLUP);
pinMode(pin2,INPUT_PULLUP);
}else{
// Set pins to input.
pinMode(pin1, INPUT);
pinMode(pin2, INPUT);
}
inverter = flipLogicForPulldown ? 1 : 0;
}
unsigned char Rotary::process() {
// Grab state of input pins.
unsigned char pinstate = ((inverter ^ digitalRead(pin2)) << 1) | (inverter ^ digitalRead(pin1));
// Determine new state from the pins and state table.
state = ttable[state & 0xf][pinstate];
// Return emit bits, ie the generated event.
return state & 0x30;
}
and here is the error message:
C:\Users\k1ypp\Documents\Arduino\MLA-controller-40-20M-with-LCD\MLA-controller-40-20M-with-LCD.ino:52:28: error: no match for call to '(Rotary) (int, int)'
Rotary rotary = rotary(2, 3);
^
exit status 1
Compilation error: no match for call to '(Rotary) (int, int)'
Unless I'm going down a rabbit hole, the *.h file is looking for a "char" but the error is complaining about an "int". I'm no expert, so maybe it is obvious, but not to me.
Thanks
Dennis