Hey guys,
i got a problem that need to manipulate the frequency that Arduino could generate, usually it is bounded by 115200 baud rate. that i would like to make a random signal such as only 0s and 1s analog output with frequency that i could change. such as 200kHz something. any ideas on programming with this?
cheers and thanks
BTW, i found cil() could turn the safe guard of the baud rate limit, yet i can only get like 4 or 8 MHZ while i cant change frequency to what i want.
115200 baud is the serial transfer limit.
You can turn pins on and off way faster than that. But if you want super-accuracy then I would suggest using a 555 circuit or oscillator.
GoForSmoke:
115200 baud is the serial transfer limit.You can turn pins on and off way faster than that. But if you want super-accuracy then I would suggest using a 555 circuit or oscillator.
erhhh..how to achieve that, turn on and off pins faster.
Are you wanting to vary the serial baud rate for some reason or just generate a random frequency from an output pin?
More details of what you are trying to achieve would help in answering your question.
Lakes:
Are you wanting to vary the serial baud rate for some reason or just generate a random frequency from an output pin?More details of what you are trying to achieve would help in answering your question.
well, thanks in advance,
what i need is to make 6 analog output with random 0 and 1 at some frequency say 200khz at the same time. will this be possible?
that i would like to make a random signal such as only 0s and 1s analog output with frequency that i could change. such as 200kHz something.
Uhhhh... What?!? 0s and 1s analog?!? 0s and 1s are by definition digital, aren't they?
Not really sure what you want the random signal to look like. You want to put out random 0s and 1s at a configurable frequency?
It is relatively easy to get the Arduino to put out a consistent square wave at a given frequency. There are tone libraries that can do that with a little work. They use hardware timers so they can continue to put out the square wave while your code does other stuff.
To just "turn pins on and off" is pretty easy as well. Turning a pin on or off is as easy as a digitalWrite() call or a bitSet() call or a PORTx = assignment. You can mess with the timing of your code if you want to try bit banging that way. The frequency will all depend on what you do between banging the bits. Mostly that would be loops or conditionals or determining whether or when to turn the next pin on or off.
The random thing might be a problem, depending on exactly how random you need it to be. At 200 KHz if you're bit banging there's only 80 clock cycles between banging the bits. That's not a whole lot for running a random function.
To do 6 of them at the same time? At 200 KHz? Good luck with that.
What is this analog output with 0 and 1 thing?
You won't generate decent pseudo-randoms that fast just using Arduino.
TanHadron:
that i would like to make a random signal such as only 0s and 1s analog output with frequency that i could change. such as 200kHz something.
oh, my bad, i m a noob in this...its possible to generate 10Khz random 0 and 1 digital signal or pseudo random bit sequence?
Lakes:
Are you wanting to vary the serial baud rate for some reason or just generate a random frequency from an output pin?More details of what you are trying to achieve would help in answering your question.
generate random signal from an output pin at 10Khz will do
How about make code to generate the sequence first and then see how fast you can get it to run? Or pre-generate randoms onto an SD card or from a PC and see how fast you can read them and spit them out?
Do a search on randoms, there was a major thread on just that months ago. If what you make falls into patterns it will show pretty soon at 10,000/second or even 100/second.
So you basically want a signal that randomly goes high and low, but the transitions are on 100 microsecond boundaries?
How random do you need your random bits to be?
Pseudorandom algorithms tend to repeat at some point or another anyway. Seeds have finite sizes. At 10KHz, you're running through your pattern pretty quickly. But that may or may not be much of a problem depending on your application. Do you have a problem if it repeats after a second or two? A minute? An hour? Do you care if it's skewed, and has 51% oness and 49% zeros?
TanHadron:
So you basically want a signal that randomly goes high and low, but the transitions are on 100 microsecond boundaries?How random do you need your random bits to be?
Pseudorandom algorithms tend to repeat at some point or another anyway. Seeds have finite sizes. At 10KHz, you're running through your pattern pretty quickly. But that may or may not be much of a problem depending on your application. Do you have a problem if it repeats after a second or two? A minute? An hour? Do you care if it's skewed, and has 51% oness and 49% zeros?
no, not at all. any ideas?
Sure. If you don't need them all that fast, you can just use a pseudo-random generator to generate bits, and shove them out the pins. Here's one:
const byte outputPinArray[6] = {8, 9, 10, 11, 12, 13}; // PB0 - PB5 These must be contiguous in order for PORTx operations to work.
void setup()
{
byte i;
for (i = 0; i < 6; ++i)
pinMode(outputPinArray[i], OUTPUT);
}
void loop()
{
static unsigned long Seed = 1;
byte j;
// This pseudo-random algorithm was pulled off Wikipedia Linear congruential generator
// The numbers were the first ones in the table, and seemed to work OK.
// It takes about 4 microseconds to calculate 32 bits
Seed = Seed * 1664525UL + 1013904223UL;
j = (Seed >> 8) & 63; // Get 6 bits, but not the lowest 6
PORTB = (PORTB & 63) | j; // Set all 6 pins
}
Actually, this turned out to be faster than I expected. I clocked it at over 200KHz.
If you need them faster but don't care as much how random they are, pre-generate a bunch of pseudo-random bits (or download some truly random bits off the internet) and store them in flash. Then just look them up and shove them out the pins.
If you need the timing to be consistent, you can use a timer to fire off an interrupt or set a bit you can poll.
TanHadron:
Sure. If you don't need them all that fast, you can just use a pseudo-random generator to generate bits, and shove them out the pins. Here's one:const byte outputPinArray[6] = {8, 9, 10, 11, 12, 13}; // PB0 - PB5 These must be contiguous in order for PORTx operations to work.
void setup()
{
byte i;
for (i = 0; i < 6; ++i)
pinMode(outputPinArray[i], OUTPUT);
}
void loop()
{
static unsigned long Seed = 1;
byte j;
// This pseudo-random algorithm was pulled off Wikipedia Linear congruential generator
// The numbers were the first ones in the table, and seemed to work OK.
// It takes about 4 microseconds to calculate 32 bits
Seed = Seed * 1664525UL + 1013904223UL;
j = (Seed >> 8) & 63; // Get 6 bits, but not the lowest 6
PORTB = (PORTB & 63) | j; // Set all 6 pins
}
Actually, this turned out to be faster than I expected. I clocked it at over 200KHz. If you need them faster but don't care as much how random they are, pre-generate a bunch of pseudo-random bits (or download some truly random bits off the internet) and store them in flash. Then just look them up and shove them out the pins. If you need the timing to be consistent, you can use a timer to fire off an interrupt or set a bit you can poll.
awesome code! thanks a lot. well, one more question, is there a frequency variable, what if i would like to change the frequency to around 10Khz?
thanks
Well, you could make it configurable or use one of the timers to get very exact. But to do it the easy way and get "about 10Khz" you could do this:
Seed = Seed * 1664525UL + 1013904223UL;
j = (Seed >> 8) & 63; // Get 6 bits, but not the lowest 6
PORTB = (PORTB & 63) | j; // Set all 6 pins
delayMicroseconds(96); // Adjust to about 100 microseconds
TanHadron:
Well, you could make it configurable or use one of the timers to get very exact. But to do it the easy way and get "about 10Khz" you could do this:Seed = Seed * 1664525UL + 1013904223UL;
j = (Seed >> 8) & 63; // Get 6 bits, but not the lowest 6
PORTB = (PORTB & 63) | j; // Set all 6 pins
delayMicroseconds(96); // Adjust to about 100 microseconds
dont know why..but i probe the output from pin 8 9 10 11 12 13..well, no random happens...always 5 V output..
Oops. I got so busy testing the random I didn't test the actual pin outs.
Change this line:
PORTB = (PORTB & 63) | j; // Set all 6 pins
To this:
PORTB = (PORTB & ~63) | j; // Set all 6 pins
TanHadron:
Oops. I got so busy testing the random I didn't test the actual pin outs.Change this line:
PORTB = (PORTB & 63) | j; // Set all 6 pins
To this:
PORTB = (PORTB & ~63) | j; // Set all 6 pins
you re the man. thanks a lot...
Now there's one I never recall using, the bitwise not (~). Always used xor and 1's.