Go Down

Topic: getting my Uno 8x8x8 led cube to run on a mega (Read 2091 times) previous topic - next topic

Roonie

Hi,

Bit of a noob here so sorry about that.
I got my 8x8x8 led cube to work perfectly on an Uno. Now I want to run the cube on a mega so that I can use the extra pins.
But the programme wont run.  :smiley-confuse:  My programming skills are limited so I was hoping that
mayby someone here could help me out ...  :)
Putting the code here exceeds the 9000 characters so I put it in the attachment, hope that was correct.

thankx

J-M-L

#1
Mar 16, 2018, 08:59 am Last Edit: Mar 16, 2018, 09:00 am by J-M-L
The tutorial states
Quote
We connected the cube like this: DATA bus: Digital pins 0-7. This corresponds to PORTD on the ATmega328 on the Arduino board, so we can use direct port access instead of Arduinos digitalWrite (which is slow). Address bus: Digital pins 8-10. This corresponds to PORTB bit 0-2. On this we HAVE to use direct port access. Arduinos digitalWrite wouldn't work with this, because you can't set multiple pins simultaneously. If the address pins are not set at the exact same time, the output of the 74HC138 would trigger the wrong latches. Output Enable: Digital pin 11. Layer transistors: Analog pins 0-5 and digital pins 12 and 13.

We had to go a bit outside the scope of the Arduino platform. The intention of Arduino is to use digitalWrite() for IO port access, to make the code portable and some other reasons. We had to sidestep that and access the ports directly. In addition to that, we had to use one of the timers for the interrupt routine.

The registers for the interrupt and timers are different on different AVR models, so the code may not be portable between different versions of the Arduino board.
So they use PORTD and PORTB (and Timer2) in the old .pde format (link to source code)

Those ports do not map to the same pins on a mega see this table for the mapping.

You would need to recompile and not use their hex file of course

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

sterretje

#2
Mar 16, 2018, 09:11 am Last Edit: Mar 16, 2018, 09:12 am by sterretje
One thing that can cause the issue is the direct register manipulation. A0 on an Uno is PC0 (as you used), on a Mega it's PF0.

You're also directly manipulating timer2; does that timer on the Mega control the same pin as on the Uno? You will have to read the datasheets and check the pin mapping Mega 2560 and ATmega8 / ATmega168; you can find better ones one the web for the latter.

Note:
J-M-L was a lot faster ;)
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Roonie

#3
Mar 16, 2018, 01:33 pm Last Edit: Mar 16, 2018, 01:50 pm by Roonie
Thankx for the reply....

But like I said bit of a noob here so things like recompile and not use their hex file or
direct register manipulation ???  Got me kind of lost.

Is it a big sketch upgrade/change to get the thing to work on a mega ??
Mayby I`ve bitten off more than I can chew.

I can manipulate the pattern a lilltle bit... but that`s about it.

again thankx for the help.....

Ronald


p.s.
On the mega pins 0-3 and 5 are on PORTE, 4 on PORTG and 6-7 on PORTH ?? correct ??
So changing the sketch would be quite a lot of work ?!?


J-M-L

#4
Mar 16, 2018, 02:54 pm Last Edit: Mar 16, 2018, 02:59 pm by J-M-L
With a bit of luck it should not be rocket science and just moving a few wires around and recompiling a slightly modified sketch...

PORTB on your UNO are digital pins 8 to 13 (the doc states using only 8-10 ?) --> So I assume that in your current set-up you have wires going from pin 8 to 10 to form the Address bus.  PORTB on your mega are digital pins 19 to 26 --> so if you don't change the code you need to move the wires from pins 8-10 (or 13 if more) to 19-21 (or 26 if more)

PORTD on your UNO are digital pins 0 to 7 and the doc seems to hint they are all used --> So I assume that in your current set-up you have wires going from pin 0 to 7 to form the Data bus. PORTD on your mega are digital pins 43 to 50 --> so if you don't change the code you need to move the wires from pins 0-7 to 43-50

The hex file has been pre-compiled for a UNO. You can't use that for a mega. So you need to recompile with a MEGA as target board but there are a few things to change in the code first:

At the start of the code in the setup() you have
Code: [Select]
for(i=0; i<14; i++)
    pinMode(i, OUTPUT);

The for loops sets pins 0 to 13 of the UNO as OUTPUT. that's because PORTB and PORTD were used.
You would need to change that to place 19-21 and 43-50 as OUTPUT and that can be done by setting the Data Direction Register correctly
Code: [Select]
DDRD = B11111111; // D43 to D50 as OUTPUT
DDRB = B11111111; // D19 to D26 as OUTPUT


then you have
Code: [Select]
DDRC = 0xff;
  PORTC = 0x00;

If you keep this as is, then you talk to PORTC directly. On a UNO this would be A0-A5 and on a MEGA that would be  A8 to A15. So you need to move your wires from A0-A5 to A8-A13

Then you have Timer2 setup.
Code: [Select]
  TCCR2A = 0x00;
  TCCR2B = 0x00;

  TCCR2A |= (0x01 << WGM21); // CTC mode. clear counter on TCNT2 == OCR2A
  OCR2A = 10; // Interrupt every 25600th cpu cycle (256*100)
  TCNT2 = 0x00; // start counting at 0
  TCCR2B |= (0x01 << CS22) | (0x01 << CS21); // Start the clock with a 256 prescaler

  TIMSK2 |= (0x01 << OCIE2A);


A timer is just a clock counter built in the Arduino controller can be programmed by some special registers.

The Arduino UNO board is based on the ATmega328 and has 3 timers, called Timer0, Timer1 and Timer2. Timer0 and Timer2 are 8bit timer, where Timer1 is a 16bit timer.

The Arduino Mega is based on the ATmega2560. It is not too far from the ATmega328 but has 6 timers. First 3 timers (Timer 0, Timer1 and Timer2) are identical to the ATmega328 (and Timer3, Timer4 and Timer5 are all 16bit timers, similar to Timer1.)

All timers depends on the system clock of your Arduino system - here on a UNO or MEGA you would be likely at 16MHz in both cases so interruption would behave the same way

Here they use Timer2 with a prescaler of 256 and an Output Compare value of 10. This means that the counter is incremented by 1 for every 256th cpu cycle. When Timer2 reaches 10, it is reset to 0 and the interrupt routine is called - this is what drives the refresh of your cube.

--> long story short as timer2 is used to drive an ISR and as the registers and configurations are the same for this setup, it should work without changes.


doing so you will end up with the following code (after removing a couple warning)

So:
you need to move the wires from pins 8-10 (or 13 if more) to 19-21 (or 26 if more)
you need to move the wires from pins 0-7 to 43-50
you need to move your wires from A0-A5 to A8-A13
you need to recompile the attached code with a MEGA as target board

and it possibly could work .... give it a try...

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

sterretje

What are you intending to do with the extra pins?
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

J-M-L

#6
Mar 16, 2018, 03:37 pm Last Edit: Mar 16, 2018, 03:38 pm by J-M-L
What are you intending to do with the extra pins?
yep that was going to be the next question

In the doc they state
Quote
We use Timer2 with a prescaler of 128 and an Output Compare value of 10. This means that the counter is incremented by 1 for every 128th cpu cycle. When Timer2 reaches 10, it is reset to 0 and the interrupt routine is called. With a cpu frequency of 14745600 Hz, 128 prescaler and output compare of 10, the interrupt routine is called every 1408th CPU cycle (128*11) or 10472.7 times per second. It displays one layer at a time, so it takes 8 runs of the interrupt to draw the entire cube once. This gives us a refresh rate of 1309 FPS (10472.7/8). At this refresh rate, the LED cube is 100% flicker free. Some might say that 1300 FPS is overkill, but the interrupt routine is quite efficient. At this high refresh rate, it only uses about 21% of the CPU time. We can measure this by attaching an oscilloscope to the output enable line (OE). This is pulled high at the start of each interrupt and low at the end, so it gives a pretty good indication of the time spent inside the interrupt routine.
but in practice the frequency is 16Mhz and the presecaler the use in the code is 256... if their assumption on the efficiency is correct then the CPU will be locked for ~50% of the time, giving an option to drive other stuff as long as it's not super time constrained


Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

sterretje

I did not even look at that; I was just wondering what the OP was planning to do what could need more pins.

We both know that there are more ways to get more pins using SPI/I2C and so on. I did not dig through the article so I do not know if pins to drive those are still available.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Roonie

#8
Mar 16, 2018, 11:25 pm Last Edit: Mar 16, 2018, 11:48 pm by Roonie
   First of all super thankx for the help guys, it`s late now here, but I wil try to read and
learn from your post this weekend, J-M-L .

What are you intending to do with the extra pins?
What I would like to do with the extra pins is connect an IR reciever and use a remote to control the led cube.
Like 1 to 9 for 9 different patterns or set it to auto run, mayby change the animation speed things like that.
Also I would like to drive a 7 segment display , displaying which pattern is active 1 to 9 or 0 for auto run.
Got these things working in a stand alone sketch, but can`t put it in the cube sketch because all the pins are taken.
Had a long look online for mayby using 2 uno`s but didn`t see how I can connect to the cube uno as all the pins are taken ....

Again thankx the help,

Ronald


p.s.
For extra information, this is the led cube I build and it was based on these instructions. Here you can also see a wiring diagrame.

sterretje

#9
Mar 17, 2018, 02:22 am Last Edit: Mar 17, 2018, 02:23 am by sterretje
Going by the below
Code: [Select]
for(i=0; i<14; i++)
  pinMode(i, OUTPUT);

That would mean that you can still use A4 and A5 for I2C peripherals and after that still have A1..A3 available.

There are I2C port expanders like the MCP 23008 (8 pins) and MCP23017 (16 pins); you can add up to 8 if needed. There is also an example how to connect two Unos using I2C.

For the IR, you can try if it works on one of the remaining pins (A1..A3). On the Uno and Mega, you will have an interrupt conflict when using Ken Shirriff's IRremote library because it also uses TIMER2_COMPA_vect; it's an easy hack to fix it.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Roonie

#10
Mar 17, 2018, 09:58 am Last Edit: Mar 17, 2018, 10:15 am by Roonie

Going by the below
Code: [Select]
for(i=0; i<14; i++)
  pinMode(i, OUTPUT);

That would mean that you can still use A4 and A5 for I2C peripherals and after that still have A1..A3 available.
But just below that code it says;

Code: [Select]
// pinMode(A0, OUTPUT) as specified in the arduino reference didn't work. So I accessed the registers directly.
  DDRC = 0xff;
  PORTC = 0x00;


doesn`t that mean that all of PORTC (pin A0 - A5) is an output  ??  :smiley-confuse:
please correct me if I`m wrong ......

sterretje

You're right, missed that; I was put on the wrong foot by the comment about A0 above that. So you are indeed using all the pins?
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

J-M-L

The original coder has made many approximations - he didn't worry about consequences on unused pins for what he was doing

So best to,look at which pins are really used and adapt
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

J-M-L

Remember that capturing IR remote control signal will depend on interrupt working at a fairly high rate (receiver class which uses the 50 microsec interrupt timer to poll the input pin) so might fail..

There are various library for polling or using interrupts to explore but you'll be likely challenged if you want to keep the same refresh rate for your cube
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Roonie

#14
Mar 17, 2018, 11:19 am Last Edit: Mar 17, 2018, 11:36 am by Roonie
Remember that capturing IR remote control signal will depend on interrupt working at a fairly high rate (receiver class which uses the 50 microsec interrupt timer to poll the input pin) so might fail..

There are various library for polling or using interrupts to explore but you'll be likely challenged if you want to keep the same refresh rate for your cube
UH ??  :smiley-confuse:

Let`s first try to make the cube work on the mega and then I`ll come back here with my IR problems.
With all the help here I think we`ll be able to get it working.

I`m now trying to make a conversion shield for the Mega to the pin out of the Uno.
Thankx to you`re explaination J-M-L , I wil rewire the Mega pins to the different Uno pins.  :)

great help, thankx

Ronald

So you are indeed using all the pins?
p.s. wiring diagram

This is from an other build but his code also works on my cube so it is fair to say that my cube is wired the same .....

Go Up