Math Note/Frequency formula

Hello, I am trying to replicate the frequency formula I found on this site Formula for frequency table
and upload it to my trinket m0 to visualise it better. But there's a problem with the code, the "n" is incrementing but not the formula. I am new to math with Arduino so all help appreciated. The q-touch code is just for conductive touch for resetting N.

#include "Adafruit_FreeTouch.h"
#define debug Serial
Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A3, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
 int n;

void setup() {
  // put your setup code here, to run once:

  debug.begin(115200);
  delay(2000);
 // while (!debug);
  debug.println("FreeTouch test");
  // initialize digital pin LED_BUILTIN as an output.

  if (! qt_1.begin())  
    debug.println("Failed to begin qt on pin A0");
}


void loop() {
  // put your main code here, to run repeatedly:
//  fn = f0 * (a)n 
//where
//f0 = the frequency of one fixed note which must be defined. A common choice is setting the A above middle C (A4) at f0 = 440 Hz.
//n = the number of half steps away from the fixed note you are. If you are at a higher note, n is positive. If you are on a lower note, n is negative.
//fn = the frequency of the note n half steps away.
//a = (2)1/12 = the twelth root of 2 = the number which when multiplied by itself 12 times equals 2 = 1.059463094359... 
  int x=48;
  int y=24;
    n++;
  int f0=440;
  int a = pow((2),1/12);
  int an=pow((a), n);
  int fn=f0*an;
  debug.print(n);  debug.print(" |-> ");  debug.println(fn);
//    static int p;
//     static int nexpo=pow((expo), n);

//  p = pow(n, expo);
 //   debug.print(" -> ");debug.println(p);     debug.print(" -> "); debug.println(nexpo);
  delay(1500);

  int counter, result1 = 0;
  counter = millis();
  result1 = qt_1.measure(); 
  if (result1>250)
  {
   n=1;
  }
}

Integer arithmetic problems. You're calculating the 12th root of 2 as an integer. The proper answer is 1.05946309436 but as integer you end up with 1 (integers being whole numbers with no decimals).

Any way there's no point recalculating that for each note. It's a constant. The 12th root of 2 is never going to be anything else. It (and f0=440) should be global constants.

Steve

Ty, would you recommend float then?

I tried running it with long data types and I added 6 decimals just to make sure it doesn’t treat it as INT but it doesn’t seem to work either
Serial print output:

14:18:23.192 -> [n=2] [a=2] [an=2] [fn=2] 
14:18:23.192 -> [ f2=440*1
14:18:23.192 ->  = 440
14:18:24.687 -> [n=3] [a=3] [an=3] [fn=3] 
14:18:24.687 -> [ f3=440*1
14:18:24.687 ->  = 440
14:18:26.203 -> [n=4] [a=4] [an=4] [fn=4] 
14:18:26.203 -> [ f4=440*1
14:18:26.203 ->  = 440
14:18:27.699 -> [n=5] [a=5] [an=5] [fn=5] 
14:18:27.699 -> [ f5=440*1
14:18:27.699 ->  = 440
#include "Adafruit_FreeTouch.h"
#define debug Serial
Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A3, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
  long n=0.000000;
  long f0=440.000000;
  long a = pow((2.000000),1.000000/12.000000);
  long an=pow((a), n);
  long fn=(f0)*(an);

void setup() {
  // put your setup code here, to run once:

  debug.begin(115200);
  delay(2000);
 // while (!debug);
  debug.println("FreeTouch test");
  // initialize digital pin LED_BUILTIN as an output.

  if (! qt_1.begin())  
    debug.println("Failed to begin qt on pin A0");
}


void loop() {
  // put your main code here, to run repeatedly:
//  fn = f0 * (a)n 
//where
//f0 = the frequency of one fixed note which must be defined. A common choice is setting the A above middle C (A4) at f0 = 440 Hz.
//n = the number of half steps away from the fixed note you are. If you are at a higher note, n is positive. If you are on a lower note, n is negative.
//fn = the frequency of the note n half steps away.
//a = (2)1/12 = the twelth root of 2 = the number which when multiplied by itself 12 times equals 2 = 1.059463094359... 
  int x=48;
  int y=24;
    n+=1.000000;



 // debug.print(n);  debug.print(" |-> ");  debug.println(fn);
debug.print("["); debug.print("n="); debug.print(n); debug.print("] ");
debug.print("["); debug.print("a="); debug.print(n); debug.print("] ");
debug.print("["); debug.print("an="); debug.print(n); debug.print("] ");
debug.print("["); debug.print("fn="); debug.print(n); debug.println("] ");
debug.print("[ ");  debug.print("f");  debug.print(n); debug.print("=");  debug.print(f0); debug.print("*"); debug.println(an);  debug.print(" = ");
  debug.println(fn); 
//    static int p;
//     static int nexpo=pow((expo), n);

//  p = pow(n, expo);
 //   debug.print(" -> "); debug.println(p);     debug.print(" -> "); debug.println(nexpo);
  delay(1500);

  int counter, result1 = 0;
  counter = millis();
  result1 = qt_1.measure(); 
  if (result1>250)
  {
   n=1;
  }
}

If you had taken the trouble to check the Arduino Reference (top of page under Resources) you would realise that long is still an integer type so that change is useless.

Float or double would be more useful but you still may not get full accuracy because most Arduinos simply do not have a data type that can give 6 decimal places. Float only gives you 6 or 7 total digits so as your frequencies exceed 1000 the best you can expect is 2 or maybe 3 decimal places e.g. 1234.56. Of course the Trinket M0 may be different, I've never seen one.

Steve

const uint8_t MIDI_NOTE_CONCERT_A = 69;  // Note A4
const float PITCH_CONCERT_A = 440.00;
const float SEMITONE = pow(2.0, 1.0 / 12.0);
const char *NOTE_NAMES_SHARP[12] = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  delay(2000);

  for (byte MIDInote = 0; MIDInote < 128; MIDInote++)
  {
    float an = pow(SEMITONE, (float)(MIDInote - MIDI_NOTE_CONCERT_A));
    float fn = PITCH_CONCERT_A * an;
    Serial.print(NOTE_NAMES_SHARP[MIDInote % 12]);  // Note name
    Serial.print((MIDInote/12) - 1);  // Octave number
    Serial.print('\t');
    Serial.println(fn, 2);
  }
}
void loop() {}

This works within a few hundredths of a Hz over almost 11 octaves (the entire MIDI range of C-1 to G9). Octave -1 isn’t much use since it is subsonic for most people.

C-1	8.18
C#-1	8.66
D-1	9.18
D#-1	9.72
E-1	10.30
F-1	10.91
F#-1	11.56
G-1	12.25
G#-1	12.98
A-1	13.75
A#-1	14.57
B-1	15.43
C0	16.35
C#0	17.32
D0	18.35
D#0	19.45
E0	20.60
F0	21.83
F#0	23.12
G0	24.50
G#0	25.96
A0	27.50
A#0	29.14
B0	30.87
C1	32.70
C#1	34.65
D1	36.71
D#1	38.89
E1	41.20
F1	43.65
F#1	46.25
G1	49.00
G#1	51.91
A1	55.00
A#1	58.27
B1	61.74
C2	65.41
C#2	69.30
D2	73.42
D#2	77.78
E2	82.41
F2	87.31
F#2	92.50
G2	98.00
G#2	103.83
A2	110.00
A#2	116.54
B2	123.47
C3	130.81
C#3	138.59
D3	146.83
D#3	155.56
E3	164.81
F3	174.61
F#3	185.00
G3	196.00
G#3	207.65
A3	220.00
A#3	233.08
B3	246.94
C4	261.63
C#4	277.18
D4	293.66
D#4	311.13
E4	329.63
F4	349.23
F#4	369.99
G4	392.00
G#4	415.30
A4	440.00
A#4	466.16
B4	493.88
C5	523.25
C#5	554.37
D5	587.33
D#5	622.25
E5	659.26
F5	698.46
F#5	739.99
G5	783.99
G#5	830.61
A5	880.00
A#5	932.33
B5	987.77
C6	1046.50
C#6	1108.73
D6	1174.66
D#6	1244.51
E6	1318.51
F6	1396.91
F#6	1479.98
G6	1567.98
G#6	1661.22
A6	1760.00
A#6	1864.66
B6	1975.54
C7	2093.01
C#7	2217.46
D7	2349.32
D#7	2489.02
E7	2637.02
F7	2793.83
F#7	2959.96
G7	3135.97
G#7	3322.44
A7	3520.01
A#7	3729.32
B7	3951.07
C8	4186.02
C#8	4434.93
D8	4698.64
D#8	4978.04
E8	5274.05
F8	5587.66
F#8	5919.92
G8	6271.94
G#8	6644.89
A8	7040.01
A#8	7458.64
B8	7902.15
C9	8372.04
C#9	8869.86
D9	9397.29
D#9	9956.09
E9	10548.11
F9	11175.33
F#9	11839.85
G9	12543.88

Why try to help people to learn programming when you can just give them a program...without giving them any understanding?

Steve

slipstick:
Float only gives you 6 or 7 total digits so as your frequencies exceed 1000 the best you can expect is 2 or maybe 3 decimal places e.g. 1234.56. Of course the Trinket M0 may be different, I've never seen one.

Since M0 is a 32-bit Arm processor, it may provide 64-bit (double) floats which would give greater resolution. It's a simple test:

Serial.println(sizeof(float));
Serial.println(sizeof(double));