#define F_CPU 16000000UL #define I2C_FREQ 100000UL #define I2C_PRESCALER 1 #define I2C_BITRATE ((F_CPU / I2C_FREQ) - 16) / (2 * I2C_PRESCALER) void i2c_init() { TWBR = I2C_BITRATE; } void i2c_start() { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))) ; } void i2c_stop() { TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); while (TWCR & (1 << TWSTO)) ; } void i2c_write(uint8_t data) { TWDR = data; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))) ; } uint8_t i2c_read_ack() { TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); while (!(TWCR & (1 << TWINT))) ; return TWDR; } uint8_t i2c_read_nack() { TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))) ; return TWDR; } const uint8_t PWM_SLAVE_ADDR = 9; bool pwm_enabled = true; float pwm_frequency = 1000.0; float pwm_duty_cycle = 0.5; void pwm_enable() { pwm_enabled = true; pwm_check_state(); } void pwm_disable() { pwm_enabled = false; pwm_check_state(); } void setPWMFrequency(float frequency) { pwm_frequency = frequency; if (pwm_enabled) { pwm_set_frequency(pwm_frequency); } } void setPWMDutyCycle(float duty_cycle) { pwm_duty_cycle = duty_cycle; if (pwm_enabled) { pwm_set_duty_cycle(pwm_duty_cycle); } } void pwm_check_state() { if (pwm_enabled) { pwm_set_frequency(pwm_frequency); pwm_set_duty_cycle(pwm_duty_cycle); Serial.print("PWM enabled. Frequency: "); Serial.print(pwm_frequency); Serial.print(" Hz, duty cycle: "); Serial.println(pwm_duty_cycle); } else { pwm_set_duty_cycle(0.0); Serial.println("PWM disabled"); } } void pwm_set_frequency(float frequency) { // TODO: Implement PWM frequency setting logic Serial.print("Setting PWM frequency to: "); Serial.println(frequency); } void pwm_set_duty_cycle(float duty_cycle) { // TODO: Implement PWM duty cycle setting logic Serial.print("Setting PWM duty cycle to: "); Serial.println(duty_cycle); } void enablePWM() { pwm_enable(); sendCommand(0x01, 0.0); } void disablePWM() { pwm_disable(); sendCommand(0x02, 0.0); } void increaseFrequency() { setPWMFrequency(pwm_frequency * 1.25); sendCommand(0x03, pwm_frequency); } void decreaseFrequency() { setPWMFrequency(pwm_frequency * 0.8); sendCommand(0x04, pwm_frequency); } void increaseDutyCycle() { if (pwm_duty_cycle < 0.9) { setPWMDutyCycle(pwm_duty_cycle + 0.1); sendCommand(0x05, pwm_duty_cycle); } else { Serial.println("Maximum duty cycle reached!"); } } void decreaseDutyCycle() { if (pwm_duty_cycle > 0.1) { setPWMDutyCycle(pwm_duty_cycle - 0.1); sendCommand(0x06, pwm_duty_cycle); } else { Serial.println("Minimum duty cycle reached!"); } } void checkButton(uint8_t pin, const char* message, void (*command)()) { if (bit_is_clear(PINC, pin)) { Serial.println(message); delay(1000); command(); } } void setup() { i2c_init(); DDRC &= ~(1 << PINC0) & ~(1 << PINC1) & ~(1 << PINC2) & ~(1 << PINC3) & ~(1 << PINC4) & ~(1 << PINC5); PORTC |= (1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3) | (1 << PINC4) | (1 << PINC5); Serial.begin(9600); Serial.println("PWM Controller started!"); sendCommand(0x01, 0.0); } void loop() { checkButton(0, "Turn on PWM!", enablePWM); checkButton(1, "Turn off PWM!", disablePWM); checkButton(2, "Increase frequency by 25%!", increaseFrequency); checkButton(3, "Decrease frequency by 20%!", decreaseFrequency); checkButton(4, "Increase duty cycle by 10%!", increaseDutyCycle); checkButton(5, "Decrease duty cycle by 10%!", decreaseDutyCycle); } // void sendCommand(uint8_t cmd, float value) { // uint16_t cmd_value = ((uint16_t)cmd << 8) | (uint16_t)(value * 16); // uint8_t upper_byte = cmd_value >> 8; // uint8_t lower_byte = cmd_value & 0xFF; // i2c_start(); // i2c_write(PWM_SLAVE_ADDR << 1); // i2c_write(cmd); // i2c_write(upper_byte); // i2c_write(lower_byte); // i2c_stop(); // Serial.print("Sent command: 0x"); // Serial.print(cmd, HEX); // Serial.print(", value: "); // Serial.print(cmd_value / 16); // Serial.print(", cmd value: "); // Serial.print(cmd_value); // Serial.print(", data bytes: 0x"); // Serial.print(upper_byte, HEX); // Serial.print(" "); // Serial.println(lower_byte, HEX); // } void sendCommand(uint8_t cmd, float value) { uint16_t cmd_value = (uint16_t)(value * 16); uint8_t upper_byte = cmd_value >> 8; uint8_t lower_byte = cmd_value & 0xFF; i2c_start(); i2c_write(PWM_SLAVE_ADDR << 1); i2c_write(cmd); i2c_write(upper_byte); i2c_write(lower_byte); i2c_stop(); Serial.print("Sent command: 0x"); Serial.print(cmd, HEX); Serial.print(", value: "); Serial.print(value); Serial.print(", cmd value: "); Serial.print(cmd_value); Serial.print(", data bytes: 0x"); Serial.print(upper_byte, HEX); Serial.print(" "); Serial.println(lower_byte, HEX); }