Show Posts
Pages: 1 2 [3] 4 5 ... 34
31  Products / Arduino Due / Re: Due audio DAC output for headphones/amplified speakers? on: September 13, 2013, 05:21:20 pm
Simply place a 4.7k resistor in series with the DAC output and the amplified speaker input, for each of the two DACs. This will protect the Due, and if the amplified speaker is truly high-impedance then this will not attenuate the volume much (and if the volume is attenuated significantly then the amplified speaker isn't high-impedance)
32  Products / Arduino Due / Re: faster micros()? on: September 12, 2013, 05:43:13 am
That won't always work - there's a small chance of the tick overflow happening between GetTickCount() and the read of SysTick->VAL, making the result off by 1000. (There's a whole thread on this somewhere)

A call to micros() should take less than a microsecond.

33  Products / Arduino Due / Re: faster micros()? on: September 10, 2013, 07:25:26 am
I do not recommend inlining micros(), because I coded it for robustness rather than speed. Inlining it will not gain you much.

Instead, if you are guaranteed that you will always be measuring strictly less than a millisecond, you can read the SysTick counter directly. The counter counts down from 83999 to 0 with each clock tick. You use it a bit like micros(), except that you have to handle the wraparound explicitly, and because it counts down the subtraction is the other way around. You could divide the result by 84 to get microseconds, but if you are after a specific delay would be better to multiply the delay you require by 84 to get it in clock ticks.

Here is an example:
Code:
// SysTick example by stimmer

void setup() {
  Serial.begin(115200);
}

void loop() {
 
  int r=random(200);
  int v=SysTick->VAL;
  delayMicroseconds(r);
  v=v-SysTick->VAL;
  if(v<0)v+=84000;
  Serial.print("delayMicroseconds(");
  Serial.print(r);
  Serial.print(") took ");
  Serial.print(v);
  Serial.print(" clock ticks, which when divided by 84 equals ");
  Serial.println(v/84);
  delay(500);
 
}

Code:
delayMicroseconds(169) took 14205 clock ticks, which when divided by 84 equals 169
delayMicroseconds(132) took 11097 clock ticks, which when divided by 84 equals 132
delayMicroseconds(117) took 9837 clock ticks, which when divided by 84 equals 117
delayMicroseconds(47) took 3957 clock ticks, which when divided by 84 equals 47
delayMicroseconds(172) took 14457 clock ticks, which when divided by 84 equals 172
delayMicroseconds(68) took 5721 clock ticks, which when divided by 84 equals 68
delayMicroseconds(180) took 15129 clock ticks, which when divided by 84 equals 180
delayMicroseconds(23) took 1941 clock ticks, which when divided by 84 equals 23
34  Products / Arduino Due / Re: VGA library - now with TV output on: September 07, 2013, 04:10:06 pm
Wow, fantastic work smiley-cool

One suggestion, if you are connecting to DAC0 and DAC1 put 4.7k resistors in series to make sure the output impedance is high enough, some of us have broken our DACs because RLOAD was too low.

I2C could come in useful, it can be used to tell the make and model of the monitor (quite easy, it's in ASCII) and the refresh rates and modes it supports (much harder, it is in a strange binary format)
35  Products / Arduino Due / Re: VGA library - now with TV output on: September 05, 2013, 02:31:17 pm
You're right about the limiting factor of processing and I/O speed. Also, grabbing a VGA signal would need 3 A/D converters running at 12.5Msps each just for 320x240 smiley

In composite mode there still isn't much processing capacity left for input. The closest thing to what you are doing that I have tried is the SD card animation demo, which loads uncompressed animations from an SD card straight into the framebuffer ram. In VGA mode the frame rate is acceptable but in composite mode it slows to a few frames per second (I can't remember exactly how slow it was, but it was unwatchable)
36  Products / Arduino Due / Re: VGA library and WiFi library conflict? on: September 05, 2013, 02:17:03 pm
I think you might have to #include <WiFi.h> after SPI.h - that's what the other WiFi examples do. I can't help much as I haven't got an Arduino WiFi shield.

As for whether the two libraries will work together, VGA is very resource intensive, but WiFi isn't. Hopefully there's a good chance of getting them to work together somehow. I've had VGA working successfully with a WiFly but that just uses serial.
37  Development / Other Software Development / Exploring millis() on: August 19, 2013, 03:42:10 pm
I'd suggest looking at 256/250:

256/250 == 256/(256-6) == 1/(1-6/256) == 1 + (6/256) + (6/256)2 + (6/256)3 + (6/256)4 + ....

This can be factored as (1+6/256)*(1+36/65536)*(1+1296/232)*.....

Which, ignoring the least significant bits for the moment, suggests code of the form:
Code:
                b+=(b*6)>>8;
                b+=(b*36)>>16;
                b+=(b*1296)>>32;

Practically for 32 bits this is:
Code:
                b+=((b>>8)*6)+(((b&255)*6)>>8);
                b+=((b>>16)*36)+(((b&65535)*36)>>16);
                b+=((b>>8)*81)>>20;                               // 81 == 1296>>4

This should be within 2 of the correct value. Getting the precise value is left as an exercise smiley-mr-green
38  Products / Arduino Due / Re: VGA library - now with TV output on: August 09, 2013, 02:56:57 pm
gadgetoid: Wow, impressive work! Thanks for the HSV code, I may well add it to the library because it would simplify my fractal demos (which use an ugly look up table at the moment)

fog44: Monochrome mode uses the SPI hardware to generate pixels. Therefore the output has to be on the MOSI pin. I am experimenting if it is possible to use the SSC hardware (in which case output would be on port A.16 / Arduino pin A0) but I don't know if it will work yet.
39  Products / Arduino Due / Re: Data loss when sending to native USB port (SerialUSB) on: July 27, 2013, 01:46:31 pm
Not yet, I'll wait until the patch is reliable before making a pull request. At the moment it's still losing data somewhere.

It can't be directly related to the issue you linked to (because UHD_ functions are for USB host, but here we are using UDD_ functions for USB device mode). However I am convinced that the bug is in libsam rather than SerialUSB.
40  Development / Other Software Development / Re: divmod10() : a fast replacement for /10 and %10 (unsigned) on: July 09, 2013, 08:36:20 am
think divmod10() should become part of the core seeing these and the above numbers.

I'm planning to release it in the next version of Teensyduino.

Stimmer, is Arduino Print LGPL ok with you?  Would you like your name to appear, other than "Stimmer" and link to this forum topic?  You deserve credit.... just let me know what should be in the comments?


Yes that's OK. Consider what I wrote to be in the public domain so anyone can use it under any license. Just put something like "this section of code based on public domain code by Stimmer, see post at forum.arduino.cc/whatever-the-url-is ".
41  Products / Arduino Due / Re: Relocatable code on: July 05, 2013, 05:17:02 am
Do you mean position-independent code? 'Relocatable' code means code with absolutes and relocation tables and is what GCC generates already. Position-independent code is code with all relative jumps and PC-offset/register-offset addressing and has no or minimal relocation tables. The relevant GCC option is -fpic. ARM code is highly position-independent anyway and there is little or no restriction on branch distance.
42  Development / Other Software Development / Re: divmod10() : a fast replacement for /10 and %10 (unsigned) on: June 28, 2013, 01:23:47 pm
There is another speed optimization to make when you are using divmod10 to convert a long into base-10 digits: Only the first few digits of a 10-digit number need full 32-bit precision. Once the high byte is 0 you only need 24 bit precision (saves at least 10 cycles), then when the two highest bytes are 0 you only need a 16 bit divmod10 (saves over a microsecond). Once the three highest bytes are 0 the 8-bit divmod10 only takes a microsecond, and for the very last digit you don't need to do a division at all.

Code:
  while(n & 0xff000000){divmod10_asm32(n, digit, tmp8);*--p = digit + '0';}
  while(n & 0xff0000){divmod10_asm24(n, digit, tmp8);*--p = digit + '0';}
  while(n & 0xff00){divmod10_asm16(n, digit, tmp8);*--p = digit + '0';}
  while((n & 0xff)>9){divmod10_asm8(n, digit, tmp8);*--p = digit + '0';}
  *--p = n + '0';

The downside is an increase in code size of about 200 bytes. I've attached a modified Print.cpp including all the assembler macros, my profiling indicates it's 0.5us-1.5us faster per digit on average (which adds up to 7us faster for 5-10 digit numbers). I have not fully tested for accuracy yet.
43  Products / Arduino Due / Re: Due native USB bidirectional I/O performance [Now with code] on: June 27, 2013, 02:26:01 pm
exedor: Try packet sizes of 36 and 43, they might help you see where your bug is smiley-wink

When using that stty hack I find it better having open(...) before system("stty ..."). It's always been reliable for me but even so I wouldn't use it in production code or code for profiling.
44  Development / Other Software Development / Re: divmod10() : a fast replacement for /10 and %10 (unsigned) on: June 26, 2013, 05:14:51 pm
As a normal function it would be dominated by overhead and marshalling. As an inline function or macro it should take 3us. The calculation is 43 instructions long, 5 of which are mul, so it takes 48 cycles in total. In a quick real-world test the result I got was 3.1245us as an inline function.

The full 32-bit range test has now completed without error smiley
45  Development / Other Software Development / Re: divmod10() : a fast replacement for /10 and %10 (unsigned) on: June 26, 2013, 10:37:35 am
Is there any reason for avoiding using mul in the assembly code? I know not all atmels have mul (I think some attinys don't) but it's there on the Uno and Mega.

Here's a version using mul and fixed point arithmetic:
Code:
void setup() {
  Serial.begin(115200);
}

void loop() {
 
  uint32_t i=1;
  uint32_t q=0;
  uint8_t r=1;
  while(1){
    uint32_t j=i;
    uint8_t k;
    uint8_t t;
    asm volatile(
   
    // this code fragment works out i/10 and i%10 by calculating i*(51/256)*(256/255)/2 == i*51/510 == i/10
   
    // by "j.k" I mean 32.8 fixed point, j is integer part, k is fractional part
    // j.k = ((j+1.0)*51.0)/256.0
    // (we add 1 because we will be using the floor of the result later)
   
      " ldi %2,51     \n\t"
      " mul %A0,%2    \n\t"
      " clr %A0       \n\t"
      " add r0,%2     \n\t"     
      " adc %A0,r1    \n\t"
      " mov %1,r0     \n\t"
      " mul %B0,%2    \n\t"
      " clr %B0       \n\t"
      " add %A0,r0    \n\t"
      " adc %B0,r1    \n\t"
      " mul %C0,%2    \n\t"
      " clr %C0       \n\t"
      " add %B0,r0    \n\t"
      " adc %C0,r1    \n\t"
      " mul %D0,%2    \n\t"
      " clr %D0       \n\t"
      " add %C0,r0    \n\t"
      " adc %D0,r1    \n\t"
      " clr r1        \n\t" 
     
     
    // j.k = j.k*256.0/255.0
    // (actually the result will always be slightly low, which we need because we use the floor of the result)
     
      " add %1,%A0    \n\t"
      " adc %A0,%B0   \n\t"
      " adc %B0,%C0   \n\t"
      " adc %C0,%D0   \n\t"
      " adc %D0,r1    \n\t"
      " add %1,%B0    \n\t"
      " adc %A0,%C0   \n\t"
      " adc %B0,%D0   \n\t"
      " adc %C0,r1    \n\t"
      " adc %D0,r1    \n\t"
      " add %1,%D0    \n\t"
      " adc %A0,r1    \n\t"
      " adc %B0,r1    \n\t"
      " adc %C0,r1    \n\t"
      " adc %D0,r1    \n\t"     
     
   
    // j.k = j.k / 2.0   
   
      " lsr %D0       \n\t"
      " ror %C0       \n\t"
      " ror %B0       \n\t"
      " ror %A0       \n\t"
      " ror %1        \n\t"   
   
   
   // now i*51.0/510.0 < j.k < (i+1.0)*51.0/510.0
   // therefore j == i/10 (since j == floor(j.k))
   // and (k*10)>>8 == i % 10
     
      " ldi %2,10     \n\t"
      " mul %1,%2     \n\t"
      " mov %1,r1     \n\t"
     
      " clr r1        \n\t"


     
      :"+r"(j),"=d"(k),"=d"(t)
      :
      :  );
     
      if((j!=q) || (k!=r)){
        Serial.print(i);Serial.print(" ");
        Serial.print(j);Serial.print(" ");
        Serial.print(k);Serial.println(" ");
      }
      if((i & 16777215)==0){Serial.print(i);Serial.print(" ");Serial.println(millis());
        if(i==0)return;}
      i++;
      r++;if(r==10){r=0;q++;}
     
  }
}

I've tested it on various values but the full test will take 6 hours to run.

My way of testing for correctness is to keep track of the expected quotient and remainder, incrementing the remainder each time the divisor is incremented and when the remainder gets to 10, increase the quotient:

Code:

  uint32_t i=1;
  uint32_t q=0;
  uint8_t r=1;
  while(1){

 [[ work out div/mod 10 of i here and check against q and r]]

      i++;
      r++;if(r==10){r=0;q++;}
     
  }


This is fast and simple, and I hope it's agreed that it is obviously a correct way of checking.
Pages: 1 2 [3] 4 5 ... 34