diff --git a/TSMP96000_Demo/TSMP96000_Demo.ino b/TSMP96000_Demo/TSMP96000_Demo.ino new file mode 100644 index 000000000..4f4063203 --- /dev/null +++ b/TSMP96000_Demo/TSMP96000_Demo.ino @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2024 ladyada for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#define IROUT 9 +#define IRIN 2 + +volatile unsigned long pulseCount = 0; + +#if defined(ARDUINO_RASPBERRY_PI_PICO) +#include "hardware/pwm.h" +void countPulse() { + pulseCount++; +} +#else +void countPulse() { + pulseCount++; +} +#endif + +void setup() { + Serial.begin(115200); + pinMode(IRIN, INPUT); // Assuming the input signal is connected to pin 2 + + attachInterrupt(digitalPinToInterrupt(IRIN), countPulse, RISING); + pinMode(IROUT, OUTPUT); + +} + +bool testFreq(uint32_t freq) { + uint32_t temp = 0; + + Serial.print(freq); Serial.println(" Hz"); + setFrequency(freq); // Set the initial frequency to the specified value + pulseCount = 0; + delay(100); + temp = pulseCount; + Serial.print("\tCounted "); Serial.print(temp); + Serial.println(" pulses"); + if ((temp > (freq / 10) + (freq / 100)) || (temp < (freq / 10) - (freq / 100))) { + return false; + } + return true; +} + +void loop() { + Serial.println("----------------------"); + if (!testFreq(30000)) return; + if (!testFreq(40000)) return; + if (!testFreq(50000)) return; + if (!testFreq(60000)) return; + +} + +void setFrequency(unsigned long frequency) { +#if defined(__AVR__) + unsigned long ocrValue; + byte csBits = 0; + + // Disable interrupts + noInterrupts(); + + // Reset Timer1 Control Registers + TCCR1A = 0; + TCCR1B = 0; + TCNT1 = 0; // Reset counter + + // Set Timer1 to CTC mode (Clear Timer on Compare Match) + TCCR1B |= (1 << WGM12); + + // Determine best prescaler and OCR1A value for the desired frequency + if (frequency > 4000) { // Can use no prescaler if frequency is high enough + csBits = (1 << CS10); // No prescaler + ocrValue = 16000000 / (2 * frequency) - 1; + } else if (frequency > 500) { + csBits = (1 << CS11); // Prescaler 8 + ocrValue = 2000000 / (2 * frequency) - 1; + } else if (frequency > 60) { + csBits = (1 << CS11) | (1 << CS10); // Prescaler 64 + ocrValue = 250000 / (2 * frequency) - 1; + } else { + csBits = (1 << CS12); // Prescaler 256 + ocrValue = 62500 / (2 * frequency) - 1; + } + + // Handle boundary conditions for OCR1A + if (ocrValue > 65535) ocrValue = 65535; // Cap at maximum for 16-bit timer + if (ocrValue < 1) ocrValue = 1; // Ensure OCR1A is at least 1 + + OCR1A = ocrValue; + TCCR1B |= csBits; // Set the prescaler + TCCR1A |= (1 << COM1A0); // Toggle OC1A on Compare Match + + // Re-enable interrupts + interrupts(); + +#elif defined(ARDUINO_RASPBERRY_PI_PICO) + // Set PWM frequency for the RP2040 + gpio_set_function(IROUT, GPIO_FUNC_PWM); + uint slice_num = pwm_gpio_to_slice_num(IROUT); + pwm_set_wrap(slice_num, 125000000 / frequency); + pwm_set_chan_level(slice_num, PWM_CHAN_A, 125000000 / (2 * frequency)); + pwm_set_enabled(slice_num, true); + +#endif +}