Question: Program Timing / Speed and Data Efficiency ?

Sorry for bothering, but I have a question where I haven't found an "elegant" solution yet because of lack of expertise.

Problem: I need to continuosly output a 72bit pattern with variable speed.
Therefore the intention is to connect a potentiometer to one of the analog input for adjusting the program speed

There are two different 72 BitPatterns which are selected by a different pin.

Now my two questions: the max frequency by which the bits should be sent to the output is about 8,5 kHz and adjustable by the potentiometer value.
How can I realize this in a smart manner?

Question two: At the moment I store the 72bits as bytes, which is a huge waste of space. I had in mind storing them as bits in µP EEprom, but do I assume correctly I can only write/read the Bits bytewise in eeprom?

Thanks for reading and your support!
BR
Ralf

//
// 72 Bit Bitfolge ausgeben ohne Delay
//
// Rechnen:
// RPM max = 7000 U/min = 117 U/s
// 117 * 72 Bit = 8424 Hz -> 0,1187 ms Periodendauer
//
// #include <EEPROM.h>


byte OUTPin=13;  	          // Signal Output Pin
byte MPIPin=12;	              // Signal select pin
int analogPin = A3;	          // Analog Input
int analogVal = 0; 			  // Analog Value


// SPI Pattern   18-1 *2 = 72 Bit
int mySPI[72] =
{ 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0
};


// MPI Pattern
// 13 Zähne
// 1 Lücke
// 3 Zähne
// 1 Lücke
// 14 Zähne
// 1 Lücke
// 2 Zähne
// 1 Lücke


int myMPI[72] =
{ 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0
};

void setup()
{
	pinMode(OUTPin, Output};
	pinMode(SELECTPin, Input_pullup);
	}
	
	
void loop()
{
	//
	analogVal = analogRead(analogPin);  // read the input pin
	//
	//
	if (MPIPin = HIGH)
		{ for (int i =0 ; i<= 71; i++)
			if (myMPI(i) == 1) {			{
			digitalWrite(OUTPin, HIGH);
			}
			else
			{
			digitalWrite(OUTPin, LOW);
			}
		}
		else
		{ for (int i =0 ; i<= 71; i++)
			if (mySPI(i) == 1)
			{
			digitalWrite(OUTPin, HIGH);
			}
			else
			{
			digitalWrite(OUTPin, LOW);
			}
		}
}

do I assume correctly I can only write/read the Bits bytewise in eeprom

You are correct, but you could, of course, read a byte from EEPROM then iterate through its bits

How often will the data in EEPROM need to be updated ?

Incidentally this

if (MPIPin = HIGH)

is wrong 2 ways

= for assigment
== for comparison, and you are testing the value of the pin not its state. You need to use digitalRead() to get its state

Thanks for the comments!

The EEprom ony needs to be written once. From that point on the bits are static.
I would write a kind of marker in the EEprom, which signals that the data is already present., but this should not be part of this questions

For the error: sure... what I did was a rough idea what it should be ... just to explain what I have in mind.
I really don't like the "delay" function

I really don't like the "delay" function

Then don't use it

Take a look at Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

Set up a variable square wave, when it goes high, grab the value, when it goes low, output that value. While this is going on read the POT and use that to set the frequency of the square wave. Is there any pause between string outputs? Or is it a constant stream of bits?

How long does an Analog read take anyway? He's ony got about 1/10 of a millisecond between port writes.

-jim lee

Thanks to both!

The idea of using the millis() time ist great, but in my case far too slow. As mentioned by Jim, I'm in the range of 0,12ms.

The stream is meant to be running continuosly, so when at the end of the 72 bits, start over from beginning. If there are small hicups when reading a new analog value (maybe every second), that sould not be a huge problem.

How do I "Set up a variable square wave" ? You mean externally?

If it can't be solved in code easily, there would be the option using a variable clock source for the whole µP and adjusting speed via that. What would you recommend?

dougie_de:
Question two: At the moment I store the 72bits as bytes, which is a huge waste of space.

It's only a waste of space if you NEED the space for something else.

...R

Robin2:
It's only a waste of space if you NEED the space for something else.

...R

Sure! But I try doing things right at the first time. There certainly will be occasions where space is sparse. :wink:

But I try doing things right at the first time

What is right for one situation may not be right for another. It's horses for courses, not one size fits all

If you are looking for speed rather than saving memory then you may use different solutions

dougie_de:
Sure! But I try doing things right at the first time.

The cost of programmer time is also part of the equation.

Generally speaking memory is far far cheaper than programmer time.

...R

Okay... then it seems more clear to me now...

Will use simple code and manage speed with an LTC1799cs5 as external Clock Source ...
Will be okay from 1kHz up to 20MHz in my setup

One way to do this is use a timer to create a square wave on a pin, and program its registers to
effect a change in frequency.

A pin-change interrupt is then used to sense when the pin toggles, and this drives the bit pattern output
on a different pin.

The timing comes from the timer, the ISR then tracks this with only a small latency and jitter.
The rest of your code can run independently which is nice.

You have to figure out controlling a timer directly though, or find a suitable library to do this.

You can try this to see if this'll go as fast as you need.

#include <mechButton.h>

#define  SELECT_PIN     2
#define  OUT_PIN        13
#define  NUM_VALUES     72
#define  BIT_MS         100 //Bits per second. This can be a real number like 0.1


int mySPI[72] =
{ 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0
};

int myMPI[72] =
{ 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0
};

mechButton  selctor(SELECT_PIN);
timeObj     bitTimer;
int         arrayIndex;


void setup() {
   
   pinMode(OUT_PIN, OUTPUT);
   arrayIndex = 0;
   bitTimer.setTime(BIT_MS);
   bitTimer.start();
}
   
   
void loop() {

   if (bitTimer.ding()) {
      if (selctor.trueFalse()) {
         digitalWrite(OUT_PIN,myMPI[arrayIndex++]);
      } else {
         digitalWrite(OUT_PIN,mySPI[arrayIndex++]);
      }
      if (arrayIndex>=NUM_VALUES) {
         arrayIndex = 0;
      }
      bitTimer.stepTime();
   }     
}

It uses a button to switch arrays of values. And it doesn't start over when switching arrays. But you can play around with it and see if it can go fast enough. If so you could add a POT to this and have that adjust the bitrate by resetting the timer setting. You'll need to instal LC_baseTools from the IDE library manager to compile this.

Good luck!

-jim lee

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.