Skip to content

Instantly share code, notes, and snippets.

@markterrill
Created September 7, 2015 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markterrill/dab3fc49cddd14c971e2 to your computer and use it in GitHub Desktop.
Save markterrill/dab3fc49cddd14c971e2 to your computer and use it in GitHub Desktop.
#define FAN1 D0 // A4 on old board, A0 on new board but photon doesn't have PWM etc on A0
// PWM
//#define PWM_FREQ 25000 // in Hertz (SET YOUR FREQUENCY) for analogWrite2
// TURN DEBUG ON?
#define MYDEBUG TRUE
int tinkerAnalogWrite(String command);
int percent = 0, dacp = 0;
void setup() {
// Start serial at 9600 baud
Serial.begin(9600);
pinMode(FAN1, OUTPUT);
analogWrite(FAN1, 0);
Spark.function("analogwrite", tinkerAnalogWrite);
Serial.println("Started up!");
}
void loop() {
percent += 10;
if (percent > 100){
percent = 0;
}
//percent = 30;
// Use PWM function
analogWrite2(FAN1, percent);
//analogWrite(DAC1, percent / 100 * 4095);
delay(4000);
}
void analogWrite2(uint16_t pin, double percent) { //Originally using and Bdub's code
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
STM32_Pin_Info* PIN_MAP = HAL_Pin_Map();
uint16_t Prescaler; // 0.. 65,535
uint16_t Period; // 0.. 65,535
uint16_t Value; // 0.. 65,535
// !! Prescaling doesn't appear to work! if you use a value less than 65534 (uint8_max) I could not get 100%
//Prescaler = (((SystemCoreClock / 24000) / 2) - 1); // As SystemCoreClock is 120000000 (120Mhz) on STM32F2/F4, this is setting it to 24hz frequency
//Prescaler = ((SystemCoreClock / 1000000) / 2) - 1; // Get clock to 1 MHz on STM32F4
//Prescaler = (SystemCoreClock / 24000000) - 1; // Get clock to 24 MHz
//Period = 65535 - 1;
// Value = ((percent / 100) * (Period + 1) ); // ie 0...[Period]
//Seem to use uint8_max regardless, observed by setting period to 1000 and a value of 1000, it doesn't have a meaningful effect.
// Only when setting value to 65k can you see the motor at full
//Period = 65535 - 1;
// Calcs sourced from http://stm32f4-discovery.com/2014/05/stm32f4-stm32f429-discovery-pwm-tutorial/
Prescaler = 0; //(SystemCoreClock / 120000000) - 1;
Period = SystemCoreClock / 25000 - 1;
Value = ((Period + 1) * percent) / 100 - 1;
Serial.println(" ");
Serial.print("System clock: ");
Serial.println(SystemCoreClock);
Serial.print("analogWrite2 ");
Serial.print(percent);
Serial.print("% on PIN ");
Serial.print(pin);
Serial.print(" pre: ");
Serial.print(Prescaler);
//Serial.print(" pcCalc: ");
//Serial.print(percentCalc);
Serial.print(" period: ");
Serial.print(Period);
Serial.print(" value: ");
Serial.println(Value);
// Don't re-init PWM and cause a glitch if already setup, just update duty cycle and return.
if (PIN_MAP[pin].pin_mode == AF_OUTPUT_PUSHPULL) {
Serial.print("second time around, just setting speed to ");
Serial.println(Value);
Serial.print("perip:");
if (PIN_MAP[pin].timer_peripheral == TIM4){
Serial.println(" TIM4");
} else {
Serial.println(" TIM not known!!");
}
//TIM_OCInitStructure.TIM_Pulse = TIM_CCR;
TIM_OCInitStructure.TIM_Pulse = Value;
if (PIN_MAP[pin].timer_ch == TIM_Channel_1) {
Serial.println("modifying TIM1");
PIN_MAP[pin].timer_peripheral-> CCR1 = TIM_OCInitStructure.TIM_Pulse;
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) {
Serial.println("modifying TIM2");
PIN_MAP[pin].timer_peripheral-> CCR2 = TIM_OCInitStructure.TIM_Pulse;
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) {
Serial.println("modifying TIM3");
PIN_MAP[pin].timer_peripheral-> CCR3 = TIM_OCInitStructure.TIM_Pulse;
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) {
Serial.println("modifying TIM4");
PIN_MAP[pin].timer_peripheral-> CCR4 = TIM_OCInitStructure.TIM_Pulse;
} else {
Serial.println("did not find a TIM match");
Serial.println(PIN_MAP[pin].timer_ch);
}
return;
}
// TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100
//uint16_t TIM_CCR = (uint16_t)(value * (TIM_ARR + 1) / 255);
pinMode(pin, AF_OUTPUT_PUSHPULL);
// Random guess
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* Time base configuration */
//TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; // Get clock to 1 MHz on STM32F2/F4
//TIM_TimeBaseStructure.TIM_Prescaler = Prescaler; // Get clock to 1 MHz on STM32F2/F4
TIM_TimeBaseStructure.TIM_Prescaler = Prescaler; // Get clock to 1 MHz on STM32F2/F4
TIM_TimeBaseStructure.TIM_Period = Period;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, &TIM_TimeBaseStructure);
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
//TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, &TIM_BaseStruct);
/* Enable TIM1 Preload register on ARR */
//TIM_ARRPreloadConfig(TIM1, ENABLE);
/* TIM PWMn Mode configuration */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // default, set on compare match
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = Value;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
delay (3000);
if (PIN_MAP[pin].timer_ch == TIM_Channel_1) {
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
// PWM1 Mode configuration: Channel1
TIM_OC1Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure);
TIM_OC1PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable);
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) {
//TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
// PWM1 Mode configuration: Channel2
TIM_OC2Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure);
TIM_OC2PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable);
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) {
//TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM3;
// PWM1 Mode configuration: Channel3
TIM_OC3Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure);
TIM_OC3PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable);
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) {
//TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM4;
// PWM1 Mode configuration: Channel4
Serial.println("modifying TIM4 below");
TIM_OC4Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure);
TIM_OC4PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable);
}
TIM_ARRPreloadConfig(PIN_MAP[pin].timer_peripheral, ENABLE);
/* TIMn Main Output Enable */
TIM_CtrlPWMOutputs(PIN_MAP[pin].timer_peripheral, ENABLE);
// TIM enable counter
//TIM_Cmd(PIN_MAP[pin].timer_peripheral, ENABLE);
TIM_Cmd(TIM4, ENABLE);
}
int tinkerAnalogWrite(String command){
int pinNumber = command.charAt(1) - '0';
int rangeMin = 40;
int rangeMax = 100;
//int range = rangeMax - rangeMin;
rangeMin = 0;
int range = 255;
if (pinNumber< 0 || pinNumber >7) return -1;
String value = command.substring(3);
if(command.startsWith("D")){
pinMode(pinNumber, OUTPUT);
analogWrite(pinNumber, value.toInt());
return 1;}
else if(command.startsWith("A")){
pinMode(pinNumber+10, OUTPUT);
if (value.toFloat() == 0){
analogWrite2(FAN1, 0);
Serial.println("turning off");
} else {
analogWrite2(FAN1, value.toInt());
Serial.print("Doing manual speed on PIN ");
Serial.print(FAN1);
Serial.print(" value: ");
Serial.println(value.toInt());
//analogWrite2(pinNumber+10, ((value.toFloat() / 255.0) * range) + rangeMin);
}
//analogWrite(pinNumber+10, value.toInt());
return 1;
}
else return -2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment