Hallo Warum kann ich, oder die ArduinoIDE, keine Welle machen ;-) j läuft von 0-33 immer wieder hoch und ich hätte gerne halbe (positive) Sinuswellen über die Schleife: Die map() Funktion kann wohl nur mit ganzen Zahlen rechnen, aber ich kann es auch nicht nachträglich erzwingen: float tick = sin(map(j, 0, 33, 0, 3141)/1000); gibt nur das aus: 0 0.00 ... 10 0.00 11 0.84 ... 21 0.84 22 0.91 ... 31 0.91 32 0.14 33 0.14
Dein "map(...)/1000" ergibt nur ints. Mach mal nen "map(...)/1000.0" raus, dann macht er ne float-Division.
Kolja L. schrieb: > Die map() Funktion kann wohl nur mit ganzen Zahlen rechnen, > aber ich kann es auch nicht nachträglich erzwingen: > > float tick = sin(map(j, 0, 33, 0, 3141)/1000); > > gibt nur das aus: > > 0 0.00 > ... > 10 0.00 Und was gefällt dir daran nicht? Was erwartest du? map() ist in Arduino als long deklariert, d.h. liefert nur ganze Zahlen. https://www.arduino.cc/reference/en/language/functions/math/map/ Durch 1000 dividiert bekommst du also auch ganze Zahlen, d.h. es können die Werte 0,1,2 oder 3 auftreten. Für die sin()-Berechnung werden die automatisch in float gekastet und die Funktion liefert dir genau die Werte 0.84, 0.91, 0.14 oder 0.00 Der Rechner macht genau das, was du ihm gesagt hast ;-)
@Kolja L. (kolja82) >Warum kann ich, oder die ArduinoIDE, keine Welle machen ;-) Du kannst es nicht. >j läuft von 0-33 immer wieder hoch und ich hätte gerne halbe (positive) >Sinuswellen über die Schleife: Und warum nimmst du dafür nicht wie jeder einfac die Sinusfunktion mit passender Skalierung? >Die map() Funktion kann wohl nur mit ganzen Zahlen rechnen, Die ist was für Knalltüten, die nicht mal 7. Klassemathematik beherrschen. float tick = sin(3.1415/33*j); Der Parameter von Sinus ist ein Winkel im Bogenmaß, 0-2Pi. Du willst nur bis Pi rechnen (halber Sinus), also muss man bei j=33 auf Pi kommen.
An dieser Stelle würde allerdings nicht die Rechenintensive Sinus Funktion benutzen, sondern eine Übersetzungstabelle, die ich vorher mit einer Tabellenkalkulation erstellt habe.
1 | float sinus_tabelle[]={0.098, 0.195, ... }; |
2 | float sinus=sinus_tabelle[j]; |
Um RAM zu sparen, könnte man diese Tabelle im Flash Speicher halten (mit PROGMEM). Auch würde ich vermeiden, das Ergebnis als Fließkommazahl weiter zu verarbeiten. Am Ende wirst du sehr wahrscheinlich etwas digitales steuern, was Boolean oder Integer benötigt. Ein PWM Ausgang braucht zum Beispiel 8bit Werte zwischen 0 und 255, nicht Float zwischen 0 und 1. Das kannst du bereits in der Übersetzungstabelle berücksichtigen.
#include <math.h> unsigned char fe[32]; int i; void setup() { Serial.begin(9600); // Tabelle aufstellen for (i = 0; i < 32; i++) fe[i] = 127 + 127 * sin( i / 32.0 * 3.1415 ); // Tabelle ausgeben for (i = 0; i < 32; i++ ) Serial.println((int)fe[i]); } void loop() { }
Stefanus F. schrieb: > sondern eine Übersetzungstabelle, die ich vorher mit > einer Tabellenkalkulation erstellt habe. Oder einfach online: http://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml Macht dir ne Copy&Paste Tabelle, die direkt in C passt.
Oder on-the-fly ausrechnen:
1 | uint8_t sine_wave[ 256]; |
2 | |
3 | void calculate_sine( void) |
4 | {
|
5 | int16_t x = 0; |
6 | int16_t y = 8180; |
7 | for( int i = 0; i < 256; i++) |
8 | {
|
9 | x = x + ( y * 4) / 163; |
10 | y = y - ( x * 4) / 163; |
11 | sine_wave[i] = 128 + ( x >> 6); |
12 | }
|
13 | }
|
Hallo Tim, danke für das Programm und um eine Programmerklärung.
Hallo Tim, danke für das Programm und bitte um eine Programmerklärung.
max123 schrieb: > danke für das Programm und bitte um eine Programmerklärung. Ich habe die Funktion ursprünglich hier gefunden: http://www.technoblogy.com/show?22HF Dort wird sie als "Minsky circle algorithm" beschrieben. Für mich sieht es nach einem "Equi-amplitude staggered update oscillator" aus. Ein bischen Theorie dazu ist u.a. hier zu finden: http://www.usbsoundcard.com/images/pdfs/digital_resonators.pdf Immerhin mit dem Verweis, das das grundlegende Verfahren schon 1572 von François Viète beschrieben und genutzt wurde...
Tim schrieb: > Immerhin mit dem Verweis, das das grundlegende Verfahren schon 1572 von > François Viète beschrieben und genutzt wurde... Das muß aber dann auf einem Rechner noch vor dem Robotron R300 gewesen sein. ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.