I would like to generate a TTL signal using an Arduino.
As far as I understand, a TTL signal is just a predefined controlled signal that repeats at a certain interval (e.g. 2 μs).
An Arduino circuit arguably has a very fast clock (e.g. 16 MHz), so what I thought is I can basically just draw a square signal for whatever desirable interval (important to be down to the microsecond).
I used the following code, choosing a pin and changing its signal state between 0 and 1 and then using Serial.println
to draw the signal out. Everything is inside a while loop that times everything to be generated exactly within 1 second.
#include <arduino-timer.h>
// Variables
unsigned long v = -1;
int freq = 100.0; // Hz
unsigned long d = floor(1.0/freq*1000000.0) ; // us
Timer<1, micros> timer; // create a timer with 1 task and microsecond resolution
void setup() {
unsigned long repeatEvery = 5000000; // Microseconds
Serial.begin(9600);
pinMode(3, OUTPUT);
timer.every(repeatEvery, func1); // XXXXX microsec
}
void func1() {
unsigned long uSec = 1000000; // Microseconds (= 1 sec)
PORTD = B00000000;
v = digitalRead(3);
unsigned long counter = 0, i = 0;
auto currentTime = micros();
auto prevTime = currentTime;
d = 0; // no delay to check the speed of the execution
do {
PORTD = B00001000;
v = digitalRead(3);
// Serial.println(v);
PORTD = B00001000;
v = digitalRead(3);
// Serial.println(v);
delayMicroseconds(d); // first frame
PORTD = B00000000;
v = digitalRead(3);
// Serial.println(v);
PORTD = B00000000;
v = digitalRead(3);
// Serial.println(v);
delayMicroseconds(d); // second frame
currentTime = micros();
i = (unsigned long)(currentTime - prevTime);
counter++;
} while(i < uSec);
Serial.print(">>>Counter:");
Serial.println(counter);
Serial.print(">>>delay (ms):");
Serial.println(d);
}
void loop() {
timer.tick();
}
The code above will give output as counter = 47620 // how many times the instructions were repeated
and if the Serial.println
lines were uncommented to draw the signal then the execution time slows down to counter = 86
I am not sure if the whole train of thought is wrong and I should do something else or use a different circuit.
Any hint or help would be highly appreciated.
PS: my Arduino by the way is a UNIROI that is supposed to be the same as an Arduino R3.
1 Answer 1
The 1u/2us are pretty fast - you have 16 or 32 instruction cycles @16MHz.
And now you have digitalRead that usually takes around 70 instruction cycles (several times), after that 32b arithmetics (hundreds instructios).
When you uncomment Serial.printlns that starts being blocking after the internal buffer is filled plus you even use 9600bauds speed (960 characters per second max speed), each println means 3 characters and it's there 4 times -> 960/12 = around 80 loops per second. Do you see the pattern?
The only way to generate jitter free signals are timers (probably fast PWM with prescaler=1 and top value according to your desired period).
-
I see the problem already yeah and thanks for the answer. The thing is that, I am not too familiar yet with all these electronic circuits (instructions). So I would appreciate a link or more details that could help putting me on the right track.wisdom– wisdom02/13/2024 22:00:30Commented Feb 13, 2024 at 22:00
-
It'd be "AVR instruction set manual", however for the Timer setting the "Atmega328p datasheet" will be more interestingKIIV– KIIV02/13/2024 22:25:29Commented Feb 13, 2024 at 22:25
TTL signal is just a predefined controlled signal that repeats at a certain interval
... no TTL is a logic level that is 5 V when high and 0 V when low ... it does not necessarily repeat ... it could easily always be high