Show Posts
Pages: 1 2 [3] 4 5 ... 14
31  Community / Exhibition / Gallery / Re: Scrolling LED matrix display - Parola for Arduino on: December 01, 2013, 05:09:30 am
Some basic questions:

1) How big are the displays? (I mean in millimeters)
2) At what frequency do the displays flicker? From what I understand, all such displays do flicker; it's just a question of at what rate. If the rate is poorly chosen, the display will be annoying if not painful to look at.
3) How would I go about changing the font?

Note: if the digits are not all the same width, then if you have a clock showing seconds, the numerals will jump around on you.
32  Community / Exhibition / Gallery / Re: Scrolling LED matrix display - Parola for Arduino on: December 01, 2013, 04:58:19 am
Great stuff.  Of course I'll have Popcorn playing on tight rotation on brain-FM now for the rest of the afternoon after your video smiley
That song is a tango, believe it or not. At least I've heard it used as one.

33  Using Arduino / Project Guidance / Re: LED pocket watch with Arduino mini? on: December 01, 2013, 04:41:04 am
diameter: 1.56 inches / 39.624 mm
depth: 0.52 inches / 13.208 mm

Did you start with measurements in hundredths of an inch, and then convert to millimeters?
If so, then there is no way you could get accuracy of 0.001 millimeter out of that.
You'd be accurate to within maybe two tenths of a millimeter, but that's all.
34  Community / Exhibition / Gallery / Re: seconds timekeeping and time conversion on: November 29, 2013, 12:25:57 pm
If I were doing this, I would use (x >> 10) as an approximation to (x / 1000), and then use the successive subtraction to clean up.

In my experience, division by constants is not as simple as you make out.  This has a lot of detail:
http://www.hackersdelight.org/divcMore.pdf

Hacker's Delight gives this solution for unsigned division by 1000, which, on AVR, is probably as bad as the division.  AVR is rotten at shifts, and all these C shifts will suck next to the hand-optimized shifts in the GCC division.

Code:
unsigned divu1000(unsigned n) {
unsigned q, r, t;
t = (n >> 7) + (n >> 8) + (n >> 12);
q = (n >> 1) + t + (n >> 15) + (t >> 11) + (t >> 14);
q = q >> 9;
r = n - q*1000;
return q + ((r + 24) >> 10);
}
Maybe the author of that code had an "avoid branching at all costs" mentality, but I don't.
My method is a compromise: first approximate n/1000 as n/1024, and then clean up by using a loop for the remaining subtractions.
You could also iterate the n>>10 trick, as follows:

Code:
unsigned divu1000(unsigned n) {
  unsigned q = 0;
  unsigned r = n + 24;
  unsigned t;
  while (r >= 1024) {
    t = (r >> 10);  // (r >> 10) + (r >> 16) is maybe better
    q += t;
    t += (t << 1);
    r = (r & 1023) + (t << 3);
  }
  return q;
  // if you want the remainder:
  // r -= 24;
  // return r;
}
or, using multiplication instead of most of the shifts,
Code:
unsigned divu1000(unsigned n) {
  unsigned q = 0;
  unsigned r = n + 24;
  unsigned t;
  while (r >= 1024) {
    t = (r >> 10);  // (r >> 10) + (r >> 16) is maybe better
    q += t;
    r -= (1000 * t);
  }
  return q;
  // if you want the remainder:
  // r -= 24;
  // return r;
}
35  Community / Exhibition / Gallery / Re: seconds timekeeping and time conversion on: November 29, 2013, 04:56:57 am
It is computing:

Code:
sysTime += (millis() - prevMillis) / 1000L;

But doing the division through successive subtraction.  But it is also working around some subtitles subtleties of unsigned subtraction that this simplification gets wrong, and keeping track of the division remainder for next time.  The assumption is that (millis() - prevMillis) / 1000L almost always is 0 or 1, and in this case subtraction is way way way faster than doing the division.

Recently, I've been working on killing a lot of division.
If I were doing this, I would use (x >> 10) as an approximation to (x / 1000), and then use the successive subtraction to clean up. (The >> symbol is the bit shift operator. On non-negative integers, (x >> 10) works out exactly the same as (x / 1024).)
36  Community / Exhibition / Gallery / Re: seconds timekeeping and time conversion on: November 27, 2013, 11:12:06 pm
Has this been tested well? (Even professionals mess up calendar stuff: google "leap year bug").

By the way, I see you have lots of divisions. I wonder how hard it would be to replace them with bit shifts and addition.
1/60 = 0x0.04444444... (abuse of notation, I know, but you get the point)
1/24 = 0x0.0AAAAAAA... (AAAAAAA!! is how I feel about the slowness of division)
37  Using Arduino / Project Guidance / Re: arduino to do something every 5 days. overcome millis() overflow?? on: November 27, 2013, 10:38:49 pm
I'm surprised nobody used this an an analogy:

Let's say you start on a road trip. At the beginning of the trip, your odometer shows 99200. At the end of the trip, the odometer shows 00700. How many miles did you drive?

Did you have trouble doing the arithmetic for that one?
What trick did you use to do the arithmetic?
The Arduino already knows -- and uses -- the same trick. You don't need to worry about overflow, as long as you stick to intervals shorter than seven weeks. Since you're only going up to five days or so, there is no problem.
38  Using Arduino / Programming Questions / Re: Unable to pad zeros on Speedometer code. on: November 26, 2013, 05:04:19 pm


Code:
tft.setCursor(45,60);
  if(KMPH==0)
  {
    tft.setCursor(45,60);
    tft.setTextColor(ST7735_RED,ST7735_BLACK);
    char buffer[4];
    sprintf(buffer, "%03.3d", KMPH);
    tft.println(buffer);
  }
  else tft.print(KMPH);

What elementary mistake am I committing now?

In this case, the sprintf() statement is a red herring: whenever the speed is not zero, you don't reach it. Look again at your braces.
39  Using Arduino / Programming Questions / Re: Unable to pad zeros on Speedometer code. on: November 26, 2013, 03:31:23 am
The way I see it, the real problem here is Adafruit's documentation on how to use these displays.
The documentation is hard to find, hard to use, and very incomplete. From what I gather, when people have problems with it, they tend to blame themselves rather than Limor and her crew.
Once I had problems similar in spirit to yours, but with a different display. It took me quite a bit of fancy detective work to figure out how to do what I needed to do, because apparently their customer service didn't have all the information I needed, either.
Perhaps from Adafruit's point of view, it just isn't cost-effective to have reasonably complete documentation and knowledgeable support staff.

I'm going to go out on a limb here and guess that for strings, you can use tft.print() as well as tft.println().

Just try changing this:
Code:
 tft.setCursor(45,60);
  tft.println(KMPH);
to this:
Code:
 tft.setCursor(45,60);
  if (KMPH >= 0) {
    // for positive numbers
    if (KMPH < 100) tft.print("0");
    if (KMPH < 10) tft.print("0");
    tft.println(KMPH);
  }
  else {
    // for negative numbers
    tft.print("-");
    if (KMPH > -10) tft.print("0");
    tft.println(-KMPH);
  }

By the way, why is KMPH a "long int"? I would think that "int" would be enough (on this platform, it goes up to 32767).
40  Community / Exhibition / Gallery / Re: Arduino generating prime numbers on: November 25, 2013, 08:38:21 pm
From multll():
Code:
*imh += 11ULL << 32;
Eleven??
41  Community / Exhibition / Gallery / Re: Arduino generating prime numbers on: November 25, 2013, 02:14:06 am
We used BigNumber to get around the fact that intermediate results can overflow an unsigned long long in the Miller-Rabin test.  That test requires calculating ab % n for large numbers.  Using numbers that are less than 1016 - 54 bits - the results always fit into a long long, but the intermediate products that generate the exponentials can be bigger than 264.  BigNumber gets around the restriction, but at some cost in speed and storage.

This code uses function "mulmodll()," that produces the product of two unsigned long long's, modulo a third unsigned long long, without overflowing on intermediate products.  It generates the product internally as two unsigned long long's, and calculates the modulo by repeated shifts and mods.  It has its own overhead - it has to take <something> % <something else> as many as seven times.  But, it's working in native number formats, rather than in BCD, and it goes faster.

This code depends heavily on the fact that numbers bigger than 1016 aren't investigated.  That fact simplifies the 128-bit multiplication, in that certain intermediate results can't overflow, and it simplifies the mod operations, too.  The code isn't general.  It's assumptions are that the lower half of any argument times the upper half of any argument will be less than 263, and that the modulus will always be less than 256.  With 1016 = 253.15, the problem fits, with a bit or two to spare.
If you are going to take many numbers modulo the same, uh, modulus, and within the limitations you describe, then we can optimize thus:
Let's call our modulus "m". We operate under the assumption that m < MAX/512, where MAX is the biggest number our datatype can hold. If m is bigger than MAX/512, our intermediate results are likely to overflow, and we can't have that.

In the situation described in the quote above, it appears we are safe, as MAX = (2**64)-1 > 10**19, and m is at most 10**16. Let's continue with this.

As in this case our MAX is (2**64)-1, we make a table of 2**64 mod m, 2**72 mod m, 2**80 mod m, etc. To prevent overflows, we will also want the value of 2**63 mod m.

To find the value of ((2**64)*hi + lo) mod m, with hi < 2**64 and lo < 2**64, we use this algorithm:

Code:
split hi into bytes hib[0] (the lowest byte), through hib[7] (the highest byte)
let r = lo mod m
let r = r + (hib[0] * (2**64 mod m))
if (r >= 2**63) {
  let r = r - 2**63 (a bit mask will work here)
  let r = r + (2**63 mod m)
}
let r = r + (hib[1] * (2**72 mod m))
if (r >= 2**63) {
  let r = r - 2**63 (a bit mask will work here)
  let r = r + (2**63 mod m)
}
let r = r + (hib[2] * (2**80 mod m))
if (r >= 2**63) {
  let r = r - 2**63 (a bit mask will work here)
  let r = r + (2**63 mod m)
}
... until we've gone through all the bytes of hi
... and finally,
let result = r mod m
This kills most of the modulo operations.
Of course, it's untested, but I don't see why it wouldn't work.
42  Community / Exhibition / Gallery / Re: Arduino generating prime numbers on: November 25, 2013, 01:17:49 am
I think I managed to clean up your print routine a little.
WARNING: untested code!
Code:
void printll(uint64_t n) {
  // print an unsigned long long
  char figs[21];
  unsigned long exa = 0, giga = 0, ones = 0;
  ones = n;
  if (n >= 1000000000) {
    n /= 1000000000;
    giga = n;
    ones -= 1000000000 * giga;
    if (n >= 1000000000) {
      exa = n / 1000000000;
      giga -= 1000000000 * exa;
    }
  }
  if (exa) sprintf(figs, "%d%09d%09d", exa, giga, ones);
  else if (giga) sprintf(figs, "%d%09d", giga, ones);
  else sprintf(figs, "%d", ones);
  Serial.print(figs);
}
43  Community / Exhibition / Gallery / Re: Billie's Hydroponic Controller on: November 24, 2013, 10:57:31 pm
I found this in the source code:
Code:
            void fotoLoop()
            {
              lightADCReading = analogRead(lightSensor);
              // Calculating the voltage of the ADC for light
              lightInputVoltage = 5.0 * ((double)lightADCReading / 1024.0);
              // Calculating the resistance of the photoresistor in the voltage divider
              lightResistance = (10.0 * 5.0) / lightInputVoltage - 10.0;
              // Calculating the intensity of light in lux
              currentLightInLux = 255.84 * pow(lightResistance, -10/9);
            }
What is that -10/9 near the bottom?
44  Community / Exhibition / Gallery / Re: Billie's Hydroponic Controller on: November 24, 2013, 03:38:34 pm
As for the NaNs for pH: I think it is because you might have a problem writing / reading float values.
I believe in killing floating-point arithmetic whenever practical.
It is usually not difficult to find ways to avoid it.
Code:
// This is evil:
float pH = 0.0178 * sensorValue - 1.889;

// Instead, use:
int pH = (2 * sensorvalue) - ((11 * sensorValue + 9445) / 50);
// This gives you 100 times the real pH,
// so if the real pH is 5, the pH variable will be 500,
// and if the real pH is 5.25, the pH variable will be 525, etc.
// Just insert a decimal point (or decimal comma!) for display.
45  Using Arduino / Programming Questions / Re: Incorrect calculation for micros() for CPUs running at 20 MHz, 24 MHz etc. on: November 14, 2013, 01:22:53 pm
baggage
Maybe time for a fork.
No, definitely time for a fork.

Quote
new data types or interfaces
I would use assembly language for this. (Correct me if I'm wrong, but I don't think there's any rule against assembly language.)

Quote
128 clock ticks
every 128 clocks?
So make it some higher number of clock ticks, I don't care. That doesn't mean that the principle isn't sound. And this way, you don't have to muck about with fractions; and since you're using multiple-precision (i.e. more than 8 bits) arithmetic anyway, you might as well go all the way.
Pages: 1 2 [3] 4 5 ... 14