Codes works with UNO but not with Leonardo!

Hi,
This is my first week learning Arduino and for the start, I bought UNO and Leonardo, I collected the below codes from everywhere, the codes below perfectly works with UNO(no serial1) but not with Leonardo, please have time to scan the code and comment, thank you in advance.

JoshSG

#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
// constants won’t change. They’re used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int switch0=0;
void setup() {
/* Setup encoder pins as inputs */
pinMode(ENC_A, INPUT);
digitalWrite(ENC_A, HIGH);
pinMode(ENC_B, INPUT);
digitalWrite(ENC_B, HIGH);

// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
Serial.println(“Start Serial0”);
delay(1);
Serial1.begin(115200);
Serial.println(“Start Serial1”);
delay(1);
while (!Serial) { }
while (!Serial1) { }
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}

void loop(){
static uint8_t counter = 0; //this variable will be changed by encoder input
int8_t tmpdata;
/**/
tmpdata = read_encoder();
if( tmpdata ) {
Serial.print("Counter value: ");
Serial.println(counter, DEC);
counter += tmpdata;
}

// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == LOW) {
// turn LED on:
digitalWrite(ledPin, HIGH);
// print out the state of the button:
if (switch0 == 0){
Serial.print("ON ");
delay(1);
Serial.println(buttonState);
delay(1); // delay in between reads for stability
switch0=1;
}
}
else {
// turn LED off:
digitalWrite(ledPin, LOW);
if (switch0==1){
Serial.print("OFF ");
delay(1);
Serial.println(buttonState);
delay(1); // delay in between reads for stability
switch0=0;
}
}
}

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
static int8_t enc_states = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static uint8_t old_AB = 0;
/**/
old_AB <<= 2; //remember previous state
old_AB |= ( ENC_PORT & 0x03 ); //add current state
return ( enc_states[( old_AB & 0x0f )]);
}

How can that code work on a UNO? It doesn't have two serial ports. The external interrupt pins are not pins 14 and 15 on the UNO or the Leonardo.

Using one of the external interrupt pins to read the switch, rather than the encoder, is silly.

   while (!Serial1) {  }

You don't need to wait for Serial1 to start.

What does the code do on the Leonardo?

Hi,
Thanks for the reply, yes I did mention that UNO has only one Serial, anyway just now I loaded the same with some changes to removed the Serial1 thing for UNO, please see attached output, I am using just the Serial Monitor.

Thanks

#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
// constants won’t change. They’re used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int switch0=0;
void setup() {
/* Setup encoder pins as inputs */
pinMode(ENC_A, INPUT);
digitalWrite(ENC_A, HIGH);
pinMode(ENC_B, INPUT);
digitalWrite(ENC_B, HIGH);

// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
Serial.println(“Start Serial0”);
delay(1);

// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}

void loop(){
static uint8_t counter = 0; //this variable will be changed by encoder input
int8_t tmpdata;
/**/
tmpdata = read_encoder();
if( tmpdata ) {
Serial.print("Counter value: ");
Serial.println(counter, DEC);
counter += tmpdata;
}

// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == LOW) {
// turn LED on:
digitalWrite(ledPin, HIGH);
// print out the state of the button:
if (switch0 == 0){
Serial.print("ON ");
delay(1);
Serial.println(buttonState);
delay(1); // delay in between reads for stability
switch0=1;
}
}
else {
// turn LED off:
digitalWrite(ledPin, LOW);
if (switch0==1){
Serial.print("OFF ");
delay(1);
Serial.println(buttonState);
delay(1); // delay in between reads for stability
switch0=0;
}
}
}

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
static int8_t enc_states = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static uint8_t old_AB = 0;
/**/
old_AB <<= 2; //remember previous state
old_AB |= ( ENC_PORT & 0x03 ); //add current state
return ( enc_states[( old_AB & 0x0f )]);
}

Hi,
In Leonardo the only output seen in the Serial Monitor is the Switch output not with the Encoder, please see attached screenshot.

Thanks

Josh

#define ENC_PORT PINC

I wouldn't expect code that uses direct port manipulation to be portable.

Hi PaulS, Do you mean Port Manipulation will not work in Leonardo while it will work with UNO? What can you suggest then? I have the two boards side by side using the same switch with encoder.

Thanks,

JoshSG

Do you mean Port Manipulation will not work in Leonardo while it will work with UNO?

No, I don't mean that. Port Manipulation will work on both, just not the same way. Different ports and pins within ports on the two boards.

Hi PaulS,
Any sample piece of code? Sorry but thanks for your time.

Thanks,

JoshSG

Sample code of what?

I don’t have a Leonardo, but I do recall seeing this in a lot of sketches:

	while(!Serial) {
		; // wait for serial port to connect. Needed for Leonardo only
	}

Don’t know if this is your problem, but it’s worth a try.

Hi Krupsky, I'd tried that but still the same.

Thanks,

Josh

Hi James C4S, Thanks for the reply, it is how to use the Port Manipulation in Leonardo. Thanks,

Josh

As Paul said, port manipulation works the same.

THE PORT you manipulate is going to (potentially) be different since the Uno and the Leonardo use different chips with different pinouts.

JoshSG: it is how to use the Port Manipulation in Leonardo.

It is not portable, so my advice is to not do it unless you need to. Do you actually need to in this case, and if so why?

Hi, I need to read the status of the two pins at the same time where the EncoderA and EncoderB pins are connected, that is why reading the whole Port is probably the best choice.

Thanks for all the replies,

Josh

PORTC on the Uno is the analog pins.

So if you want to use port manipulation, then you need to read PORTF on the Leonardo for the analog pins. Also note that the pins are not straight forward on the Leonardo.

Of PORTF Bit 0: A5 Bit 1: A4 Bit 4: A3 Bit 5: A2 Bit 6: A1 Bit 7: A0

This is why people keep saying port manipulation isn't portable. The Pins on a Leonardo and Uno connect to different hardware. So you're going to have to write different code for each one, or live with the small delay between two individual digitalReads().

Hi James, Thanks a lot!!! now you are leading me to the right information, is this where you got it? http://arduino.cc/en/Hacking/PinMapping32u4.

Thanks again,

Josh

That's one place.

I look at the schematics for the different boards from (http://arduino.cc/en/Main/Hardware), which has the same information.

e.g. PF5 tells you that is "PORTF bit 5".

Hi James, Thanks for the information, now I know where to look for.

Thanks and best regards,

Clem