Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to create a efficient array of bytes

Status
Not open for further replies.

Rubens

New Member
Hi guys,

I´m searching for the less expensive ( in terms of processing time) way to read a large (bigger than the ram size of the pic) array of bytes. Using "Dim x(500) as byte" for example, is not possible to use due to the ram limitation. The Lookup(1.....500 bytes), 500 function works but reading these bytes in sequence is too slow for my application. Any suggestions ?

Thanks,

Rubens
 
hi Rubens,
If your array is bigger than the Ram size available in the PIC [which type is it?] how do you plan to store this 500 array.?
Could you post a little more detail of the App.
E
 
Hi Eric!
Thanks for the attention. It´s possible to save this array in the program area, like the lookup function do. Something like array of const byte,
"Const v(500) = {1,2,....500}"

It´s possible to create one by one...
Const a=1
Const b=2
.
.
.
Const n=n
 
hi,
As they are Constants located in the Program flash memory area, I can see the idea.

From your snippet using the Oshonsoft Lookup I guess you are programming in Oshon basic.?
Have you considered using an ASM Routine as part of the Basic program to read the Array.

Is it always a sequential Array location Read from Start to Finish.?

A post of your existing code would be helpful.

E
 
Last edited:
Eric,
Yes, I want to do this in Oshon basic.
ASM is an option, but the possibility to create an array of const bytes would be a nice feature to the oshon basic language.

The code and it´s variations is something like this:

option 1) dim v(500) as byte - There is a limit of 255 bytes for arrays and even using only 255, there is no sufficient space for 500 bytes in ram(PIC16f88).
option 2) const v(500)=(1,23,34,...25) (500 numbers) - does not exist, but this its what I need...
option 3) v=lookup(1,23,34....,25),i (500 numbers) I do not know if it supports arrays greater than 255 and it´s slow to retrieve the data(for my application).
option4) the ugliest, but the quickest, see below

The main code is simple retrieve the data from the array and output to portb, to feed a R2R DAC.

loop:
for i =0 to 499
PORTB =v(i)
next i
goto loop

code for option 4)

loop:
portb=1
portb=23
portb=34
.
500 lines
.
.
goto loop
 
hi Rubens,
As I recall, there is/was a limit of 255 on a Look Up table in Oshon, [its also a 'pig' to type out, as its got to be on one line!]
You could consider two, 250 byte arrays, end to end or access them alternately.?

If your Table is fixed you could use program flash memory.

Which PIC type are you using.? the 18F series has Table commands.

E
 
What kind of signal is stored in the lookup table?
Are you using interrupts to update r2r dac?
How fast is the update rate?
 
Mid range PIC at 20 Mhz can go once through the loop in ASM in about 2us with a 256 byte table.
500 byte table needs some exta code and is slower.
How much speed you need?
Do you really need a 500 byte table?
 
I just note that with a good low pass I can reduce my points to the R2R DAC to 30. So, I can work with an array in ram memory ( in oshon terms, dim v(30) as byte). It´s not a nice wave, but it´s ok for now. With this configuration I can achieve an output frequency of ~4kHz, 8bit, with a 20Mhz clock in a PIC16F88.

There are also new PICs (16F17xx) supported by PIC IDE Simulator with internal DACs, PLL and more memory that I ordered today for tests. I can say that
working with Oshon Simulator is a pleasure to develop simple circuits.
Part of the code:

dim v(30) as byte ' v will be updated in the beginning of the program with a table of data.
dim period as byte ' period will be changed by an analog signal from AD.
Define ADC_CLOCK = 4
Define ADC_SAMPLEUS = 0

main:
PORTB = v(index)
Adcin0, period ' this is a problem to the maximum frequency... too slow.
Waitus period
Goto main
 
I can achieve an output frequency of ~4kHz, 8bit, with a 20Mhz clock in a PIC16F88.

Is the 4kHz the update rate of the DAC, or the bandwidth of the signal after low-pass filter?
You suddenly go from 500 point lookup table to 30 point lookup.. I suspected that the 500 sounds too much, but reducing to 30 sound strange too. Could you give a little more information what kind of signal are you trying to generate? Or is it a big secret?
 
4kHz is the frequency of the output wave signal generated and it´s ok for me. The project is the emulation of a signal from a sensor that changes frequency in time and it´s not simetrical. The signal is not a sine wave and is frequency variable, so I think that I can't use the PWM because of the fixed filter. The reduction of 500 to 30 points was just an approach to start tests, with the PIC(16F88 at 20Mhz) I have in hands right now. What suggestions do you have to update the variable 'period', from an external potentiometer, with minimum influence in the wave generated ? Do you think keeping this loop in an interrupt routine would give better results ?

Thanks
 
What suggestions do you have to update the variable 'period', from an external potentiometer, with minimum influence in the wave generated ? Do you think keeping this loop in an interrupt routine would give better results ?

Do I understand this right, you want to repeat the signal (described by the lookup table) over and over again with a frequency set by a potentiometer.. if that is the case I have some good ideas for you. I have time a little bit later to write more.
 
Last edited:
Ok. This is one idea. I program with C, but I hope it is easy to follow with added comments. The idea scales to any lookup table with size of power of two.

C:
uint8_t  table[256]  // This is 256 point lookup table (8 bit values).
uint16_t frequency;  // This 16 bit variable determines the frequency of the signal.
uint16_t index;      // This is our "running number" that determines the index we use to read the lookup table.

while(1) // infinite loop, the goal is to run as fast as possible and maintain constant update rate.
{
    /* Calculate next index. The real index will be the high byte of the 16 bit variable.
       The low byte gives resolution to control the signal frequency */
    index = index + frequency;

    /* Update the DAC (PORTB for example) */
    PORTB = table[(index/256)]; // The division scales the index between 0...255

    /* OK.. now we need to update the "frequency variable"
       I don't think you need to do the ADC conversion every cycle.
       If you can configure your ADC in some kind of "free running mode"
       and then just keep reading the conversion result register.
       I don't use PICs, so I do not know what options you have with the ADC */
    frequency = ADC_RESULT;
}

The idea is to keep the update rate constant and control the speed (frequency) you cycle through the lookup table values. It is ok to skip values in the table when going to "high frequencies".
 
Last edited:
If all the values are fixed, you can output them out with assembler program at a rate of 2.5MHz with your processor.
 
What suggestions do you have to update the variable 'period', from an external potentiometer, with minimum influence in the wave generated ? Do you think keeping this loop in an interrupt routine would give better results ?
Thanks
You could start the ADC and read the ready flag in the main loop and if conversion is ready then change the period.
This way you don't have to wait the AD-conversion, which takes tens of microseconds.
Probably you can do this in Basic, just set and read a couple of bits in a register.
I think using interrupts would be too slow.
 
You could start the ADC and read the ready flag in the main loop and if conversion is ready then change the period.
This way you don't have to wait the AD-conversion, which takes tens of microseconds.
Probably you can do this in Basic, just set and read a couple of bits in a register.
I think using interrupts would be too slow.

Long time since using PICs, but I read the datasheet (ADC part).
So, It seems like it is possible to use the "“special event trigger” of the CCP module." to trigger the ADC conversion at constant rate.
One thing is unclear for me.. how are the ADC result registers ADRESH and ADRESL updated? Can you just keep reading them and expect them to be updated when the latest conversion is finished? If that is the case, then that is perfect setup for the solution I suggested in post #15

Reading the flag (and triggering new conversion) creates jitter to the loop (conditional), which is not good. When creating signals (or reading signals) it is important to keep the sample rate constant. (or log time with the samples)
 
Last edited:
................

Reading the flag (and triggering new conversion) creates jitter to the loop (conditional), which is not good. When creating signals (or reading signals) it is important to keep the sample rate constant. (or log time with the samples)
The jitter can be avoided, but it needs tinkering with ASM-code.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top