Overunity.com Archives is Temporarily on Read Mode Only!



Free Energy will change the World - Free Energy will stop Climate Change - Free Energy will give us hope
and we will not surrender until free energy will be enabled all over the world, to power planes, cars, ships and trains.
Free energy will help the poor to become independent of needing expensive fuels.
So all in all Free energy will bring far more peace to the world than any other invention has already brought to the world.
Those beautiful words were written by Stefan Hartmann/Owner/Admin at overunity.com
Unfortunately now, Stefan Hartmann is very ill and He needs our help
Stefan wanted that I have all these massive data to get it back online
even being as ill as Stefan is, he transferred all databases and folders
that without his help, this Forum Archives would have never been published here
so, please, as the Webmaster and Creator of this Forum, I am asking that you help him
by making a donation on the Paypal Button above
Thanks to ALL for your help!!


Arduino signal generator

Started by ayeaye, October 27, 2016, 02:33:55 PM

Previous topic - Next topic

0 Members and 5 Guests are viewing this topic.

ayeaye

Ok, now it rounds, and is a bit shorter, too.

Quote#include <avr/sleep.h>

#define BUFSIZE 60

float getvalue(const char *text)
{
   char buffer[BUFSIZE], ch;

   Serial.println(text);
   for (sprintf(buffer, ""); strlen(buffer) < BUFSIZE - 1;)
      if (Serial.available()) {
         if ((ch = Serial.read()) == '\n') break;
         sprintf(buffer, "%s%c", buffer, ch);
      }
   return atof(buffer);
}

void setup()
{
   Serial.begin(9600);
   pinMode(10, OUTPUT);
}

void loop()
{
   float frequency, duty;
   unsigned long clock, period, pulsewidth;

   frequency = getvalue("Frequency?");
   duty = getvalue("Duty Cycle?");
   clock = frequency > 300. ? 16000000l : 250000l;
   period = (unsigned long) (clock / frequency + 0.5);
   if (period < 2) period = 2;
   if (period > 65000l) period = 65000l;
   pulsewidth = (unsigned long) (period * duty / 100 + 0.5);
   if (pulsewidth < 1) pulsewidth = 1;
   if (pulsewidth > period - 1) pulsewidth = period - 1;
   /* Timer1 fast PWM mode */
   TCCR1A = _BV(WGM11) | _BV(WGM10) | _BV(COM1B1);
   if (frequency > 300.)   /* No prescaling */
      TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
   else         /* 64 prescaling */
      TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10) | _BV(CS11);
   OCR1A = period - 1;
   OCR1B = pulsewidth - 1;
   Serial.print("Frequency ");
   Serial.print((float) clock / period);
   Serial.print(", Duty Cycle ");
   Serial.println(pulsewidth * 100. / period);
   Serial.println();
   delay(100);
   while (!Serial.available()) {
      set_sleep_mode(SLEEP_MODE_IDLE);
      sleep_enable();
      sleep_mode();
      sleep_disable();
   }
   TCCR1A = _BV(WGM11) | _BV(WGM10) | _BV(COM1B1);
   TCCR1B = _BV(WGM13) | _BV(WGM12);   /* Timer stop */
   TCNT1 = 0;            /* Timer value 0 */
   digitalWrite(10, 0);         /* Output 0 */
   Serial.read();
}

ayeaye

Ok, let's make a small change, to get rid of that nasty warning. It evidently worked, and corresponded to the C/C++ standards too, but when Arduino and gnu perhaps, has such requirements about sprintf, then let it have that. The rest of the warnings there were about the Arduino system code, about its serial interface, like an unused variable there, which in no way could been caused by my code. When compiling the second time there are no warnings, it doesn't show them more, because these are not relevant to the compiled code.

Quote#include <avr/sleep.h>

#define BUFSIZE 60

float getvalue(const char *text)
{
   char buffer[BUFSIZE], ch;

   Serial.println(text);
   for (sprintf(buffer, "%c", '\0'); strlen(buffer) < BUFSIZE - 1;)
      if (Serial.available()) {
         if ((ch = Serial.read()) == '\n') break;
         sprintf(buffer, "%s%c", buffer, ch);
      }
   return atof(buffer);
}

void setup()
{
   Serial.begin(9600);
   pinMode(10, OUTPUT);
}

void loop()
{
   float frequency, duty;
   unsigned long clock, period, pulsewidth;

   frequency = getvalue("Frequency?");
   duty = getvalue("Duty Cycle?");
   clock = frequency > 300. ? 16000000l : 250000l;
   period = (unsigned long) (clock / frequency + 0.5);
   if (period < 2) period = 2;
   if (period > 65000l) period = 65000l;
   pulsewidth = (unsigned long) (period * duty / 100 + 0.5);
   if (pulsewidth < 1) pulsewidth = 1;
   if (pulsewidth > period - 1) pulsewidth = period - 1;
   /* Timer1 fast PWM mode */
   TCCR1A = _BV(WGM11) | _BV(WGM10) | _BV(COM1B1);
   if (frequency > 300.)   /* No prescaling */
      TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
   else         /* 64 prescaling */
      TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10) | _BV(CS11);
   OCR1A = period - 1;
   OCR1B = pulsewidth - 1;
   Serial.print("Frequency ");
   Serial.print((float) clock / period);
   Serial.print(", Duty Cycle ");
   Serial.println(pulsewidth * 100. / period);
   Serial.println();
   delay(100);
   while (!Serial.available()) {
      set_sleep_mode(SLEEP_MODE_IDLE);
      sleep_enable();
      sleep_mode();
      sleep_disable();
   }
   TCCR1A = _BV(WGM11) | _BV(WGM10) | _BV(COM1B1);
   TCCR1B = _BV(WGM13) | _BV(WGM12);   /* Timer stop */
   TCNT1 = 0;            /* Timer value 0 */
   digitalWrite(10, 0);         /* Output 0 */
   Serial.read();
}


ayeaye

Yes it's, quite simple. Yet i put it here, because in spite that it's simple, one should have it when one needs it. Signal generator is in fact the only thing i really need Arduino for, so far. Like all i needed for calibrating my oscilloscope, was a multimeter, and a square wave signal generator. Arduino Nano costs in ebay $2.20 with shipping, so makes sense to have it even when using it only as a signal generator. The only problem, it needs a different usb cable than the micro usb cable used for most smartphones and cameras today. It may be used for many special purposes when the need may be, like its analog comparator is fast and enables to measure a changing signals in quite many ways.

The cheaper option may be the Digispark Attiny85 board, which costs only $1.20 in ebay, and is almost the same, except that it has less pins, less memory, and only two 8 bit timers. So the signal generator code has to be somewhat modified for that, though not much, and there is not so much precision for a duty cycle. The problem with that though, is that it uses an internal 16 MHz clock, not an external quartz resonator like Arduino Nano. When using it with usb, the clock is calibrated by usb, and said to have a 1% precision, when the temperature doesn't change much that is, but when using without usb, the precision is only 10%, unless separately calibrated every time. This may be good enough for some purposes but it is not good enough for some measuring.

Magluvin

Just alternative suggestions. Had a TRS-80 color computer back in the days. I believe it was .88mhz cpu and could be over clocked some, like just below or over 1mhz. The processor had to handle all the graphics, of which would take away valuable computing power. Then my brother got a Vic-20 when it came out and it at least had sprites, in which left the cpu more time to do other things while still producing better graphics. Then I got into the Amiga 500, kinda toward the end of their life. But the graphics were incredible, mostly due to separate graphics chips. So now the cpu is able to spend all its time doing other things than producing the graphics display functions.

So I lean toward independent driver circuits when using the arduino so the arduino isnt stressed with avoiding possible little glitches of the desired output when the processor has workloads or even taking time to accept input to adjust the outputs. Anyway

Mags