Hello I'm new in Arduino, and I have an Arduino UNO so I was testing how to program it, so I started with blinking 1 led... ok it works... so i tried to modify the code to blink 4 leds in sequence... so I thought digitalWrite(0x0F,HIGH) and it will work... also when I write the code pinMode(0x0F,OUTPUT), so I wrote and compiled with no problem... but when I uploaded the program to the Atmel... It doesn't work...
So... I tried to do by steps the full sequence and it works... take a look
int del = 100;
void setup() {
pinMode(0, OUTPUT); 'I think that I can reduce this 4 lines whit pinMode(0x0F, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
}
void loop() {
digitalWrite(0, HIGH); 'I tried to write digitalWrite(0x01,HIGH);
delay(del);
digitalWrite(0, LOW);
digitalWrite(1, HIGH); 'digitalWrite(0x02,HIGH);
delay(del);
digitalWrite(1, LOW);
digitalWrite(2, HIGH);
delay(del);
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
delay(del);
digitalWrite(3, LOW);
del=del-10;
if (del < 20)
{
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
digitalWrite(3,LOW);
delay(1000);
digitalWrite(0,HIGH);
digitalWrite(1,HIGH);
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
delay(2000);
del = 1000;
}
}
If you noticed I had experience programming PIC in C... So i'm looking a way to reduce the amount of lines 'cos with PIC I just use the command PORT#=0X0FF or any value to change the port values but with that command doesn't work, how should do I do to reduce the lines?
It sounds like you are wanting to do direct I/O port manipulation, rather then using the arduino 'abstracted' pin numbers. Here is a reference section on doing that:
pinMode(), digitalRead(), digitalWrite(), analogRead() and analogWrite() work on INDIVIDUAL PINS, not on groups of pins.
pinMode(0x0F, OUTPUT) will set Pin 15 (a.k.a. Analog input 1) as an output.
digitalWrite(0x0F, HIGH) will then set Pin 15 (a.k.a. Analog input 1) to +5v.
You should avoid using Pin 0 and Pin 1 for I/O because those are the hardware serial I/O pins and you won't be able to use Serial.print() debugging messages if you use those pins for other purposes.
You can do direct port manipulation such as PORTD |= 0x3C; to turn on Pins 2,3,4 and 5. PORTD &= ~0x3C; will trurn those four pins off again.
johnwasser: pinMode(0x0F, OUTPUT) will set Pin 15 (a.k.a. Analog input 1) as an output. digitalWrite(0x0F, HIGH) will then set Pin 15 (a.k.a. Analog input 1) to +5v.
You should avoid using Pin 0 and Pin 1 for I/O because those are the hardware serial I/O pins and you won't be able to use Serial.print() debugging messages if you use those pins for other purposes.
You can do direct port manipulation such as PORTD |= 0x3C; to turn on Pins 2,3,4 and 5. PORTD &= ~0x3C; will trurn those four pins off again.
Yes I noticed that... thank you for you explaining me how manage directly those ports...
Thanks to all of you! It's working, I thought that arduino had the same hardware limitations than PICAXE but it doesn't its really cool program this staff XD XD
On a binary number, the OR operation sets any bit that is a 1 in either one or the other number. The AND operation sets any bit that is 1 in both of them. THe XOR "^" sets any bit that is a 1 in one and a 0 in the other.
Let's assume portD has a state of 00011000. If we OR a 4 (00000100) the result is 00011100) We set the 3rd bitif it wasn't already, but leave all the other bits unchanged. If they are 1's 1 OR 0 = 1. If they are 0's, 0 OR 0 = 0
If we AND the inverse of a 4 (11111011) then we clear the 3rd bit if it wasn't already because this number has a 0 at that bit so the result will.
The rest will remain unchanged. 1 AND 1 = 1, 0 AND 1 = 0.
If we XOR a 4 then that third bit will get toggled. If it was already one, then we have two ones that makes a 0. If it was a 0 it will be a 1 because we have 1 of each. The bits that are XOR'ed against the zero's will be unchanged.
Techone:
Q2 : PORTD &= ~0x04; This mean Port D .. &= AND ? <--- PORD "AND" NOT Hex value 4
This construct turns bits off. Your example already had them off so that didn't show much. This shows it better:
Port B --> 00011100
NOT 0x04 -> 11111011
AND -----> 00011000 We have turned 0x04 off
The ~ operator is really a ones-complement (negation). This is different from twos-complement (minus).
So the ones-complement is a useful way of showing the "inverse" of a number. And if you AND in the inverse of a number, you effectively clear that number (those bits) leaving the other ones untouched.
So Nadir,
Can those 3 functions be added to regular code also?
Do understand these correctly:
void portMode(uint8_t port, uint8_t mode)
turns all 8 pins on a port into inputs or outputs, comparable to using this 8 times:
pinMode (pinX, INPUT);
or
pinMode(pinX, OUTPUT);
uint8_t portRead(uint8_t port)
Reads a port's pin and returns a byte of data
void portWrite(uint8_t port, uint8_t val)
Sets the port's pins to the byte val
As I mentioned I saw these functions in Wiring source. After testing them I put them in wiring_digital.c to make them built-in.
They works well in regular code also. But you should add "false" after return of statement "if (inputregister == NOT_A_PORT) return;"
in portRead function.
CrossRoads:
in the last 2 cases, what does
cli();
do?
He is protecting the port change from interrupts. So to comment it:
uint8_t oldSREG = SREG; // remember interrupt flag (and other flags)
cli(); // turn interrupts off
*portregister = val; // do something, knowing interrupts won't occur
SREG = oldSREG; // put interrupt flag back (set it again, if it was set before)
Nadir:
They works well in regular code also. But you should add "false" after return of statement "if (inputregister == NOT_A_PORT) return;"
in portRead function.
You could return 0 (false is a bit misleading), but you can't tell the difference between supplying an invalid port (which returns zero) and reading a valid port, and them all being off (which returns zero).