For my project, using Arduino Mega, I want to send an 8 bit Binary word to a port, as outp does in C, but I can't find a short way to do it. Preferably I want to use pins 30-37 (PC0 - PC7), but my hardware can be altered. If this can be done, any advice please?
Here's the section on direct port manipulation. Have at it!
void setup() {DDRC = 0xFF;} // Set all of PORTC to outputs
void loop() {
for (int i=0 ; i<256; i++) {
PORTC = i;
}
}
Many thanks for the replies, most helpful. I uploaded the sketch from johnwasser, and all the LEDs came on, so I had to add a delay to see what was happening! Inspired, I then made this mod:
void setup() {DDRC = 0xFF;}
void loop() {
int i = random(256); {
PORTC = i;
delay (500);
}
}
Interesting that the timing can make the difference between the output being soothing or really annoying..
Another question arose though, the pinouts from port C are a surprise, pin 30 on the Mega seems to be the MSB, rather than the LSB as I expected, and wired for, so 30-37 seems to be PC7 - PC0 .... or have I screwed up somehow? This is possible as I've made my own shield from stripboard (Veroboard here in the UK) using a ULN 2803 transistor array for the LEDs and the motor(s) that I intend to drive with it. But if I have, I cannot see where.
You're shoving a signed int into a PORT that only takes a byte. I'd believe that the result of that would be weird.
void loop() {
byte i = random(256);
PORTC = i;
delay(500);
}
This is more better.
typedef unsigned char uint8_t;
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#define PORTC _SFR_IO8(0x08)
Since this results in an indirection through a volatile unsigned char pointer you can assign any size int to it and the value will get truncated:
(*(volatile unsigned char *)((0x08)+__SFR_OFFSET)) = value;
Thanks Chagrin, I uploaded your code and it worked, but I could identify no difference between that and my try with random. They both work entirely as expected. It would help if you could explain to this newbie why it might be better, though this was just a sideshow to prove that I was addressing the port in the way I wanted. Much more significant was (is?) the apparent reversal of the MSB/LSB of the port pins.
johnwasser, I don't have a clue about the purpose of your last reply. I have run again the code that you sent in your first response, and assume that, slowed down enough, the LSB LED should come on first. If that is the case, then it is on pin 37 of the digital pin section of my Mega, and the MSB is on pin 30.
Perhaps someone with 8 LEDs (okay, it can be done with less...) and a breadboard would care to write to PORTC as I have done, with the LEDs on pins 30-37, and confirm or otherwise that the printed circuit on the Arduino Mega is in fact reversed relative to the port pins on the micro. (I'd rather not prod around the micro pins with a multimeter probe) Or should this go on a different page of the Forum? Or have I missed something more?
Much more significant was (is?) the apparent reversal of the MSB/LSB of the port pins.
How did you arrive at this conclusion?
What were your observations, and how were they made?
Hi, I wired a ULN 2803 pins 1 thru 8 on my shield, to pins 30 thru 37 on the Mega. Pins 18 thru 11 then go to LEDs, supplied from +5v through a 1K resistor array. When I ran johnwasser's first code slowly, the LEDs counted from 0 to 255 in binary form, starting at pin 11, which clocks on and off as might be expected, with each count. When I changed johnwasser's code to i<16, the count occurred on pins 11 to 14 only. Hence my conclusion.