Can this code be any more compact? Variable pot to PWM for brightness control

int pwm = 0;

void setup() {
  pinMode(A2, INPUT);
  pinMode(0, OUTPUT);
}

void loop() {
  pwm = analogRead(A3);  // read current pot position
  pwm = pwm >>=2;        // convert 10 bit from read to 8 bit for PWM, discarding 2 lower bits
  analogWrite(0, pwm);   // PWM output
}

I am currently using ATTiny85 but this could fit ATTiny5 (ATTiny4 does not have analog support) and at best I got this code to 672 bytes on ATTiny85 and 456 on ATTiny5

I used bitshift because it was quicker than divide by 4 or using map to convert 10 bit input to 8 bit output.

Think the code can get any smaller?

void setup() {}

void loop() { analogWrite(0, analogRead(A3) >> 2); }

(As per sterretje's comment)

I'm not sure if below applies to your controller; you will need to check the implementation of analogWrite in the core that you use.

On e.g. an Uno, you don't need the pinMode for pin 0. The standard Arduino library does this for you.

I guess the compiler would anyway optimize a /4 to a >>2, but if you directly manipulate the ADC registers instead of using analogRead() you don’t even need that. You can specify that the result is returned, left justified into an 8bit register.
If you don’t care too much about the pwm frequency, you can do it yourself in the loop by maintaining an 8 bit counter and switching the pin on at 0 and off at the pot value . I’m not sure what the resource savings would be, though.

If all you want to do is set a PWM value off an analog pin, you can put the adc in free running mode and it will give you an interrupt every time it completes a conversion and has a new value for you.

I'm not entirely sure it will work but it only takes up 162 bytes by getting rid of the Arduino runtime libraries. This is a .c file and not a .ino file. I don't have an ATtiny core (not needed for this program) so I compiled for an Arduino UNO and #undef'd the UNO processor so I could get the defines for an ATtiny85.

TinyKnob.c:

#undef __AVR_ATmega328P__
#define __AVR_ATtiny85__ 1
#include <avr/io.h>  // includes <avr/iotn85.h> which includes <avr/iotnx5.h>


int main()
{
  // void setup()
  ADCSRA = 0;
  ADCSRB = 0;
  DIDR0 = _BV(ADC0D); // Disable digital input on ADC0
  ADMUX = _BV(ADLAR);  // Aref = Vcc, Value left justified, Channel = ADC0 (PB5)
  ADCSRA = _BV(ADEN);  // Enable ADC


  // Enable PWM, Normal PWM, prescale=1
  TCCR1 = _BV(PWM1A) | _BV(COM1A1) | _BV(CS10); 


  // void loop()
  while (1)
  {
    // analogRead()
    ADCSRA |= _BV(ADSC);  // Start Conversion
    while (ADCSRA & _BV(ADSC));  // Wait for conversion to complete


    OCR1A = ADCH;  // analogWrite()
  }
}

pwm = pwm >>=2; What's that?

TheMemberFormerlyKnownAsAWOL:
pwm = pwm >>=2; What's that?

https://www.arduino.cc/en/pmwiki.php?n=Reference/Bitshift

Bit shifts 2 units over. Example: Arduino has a pwm value of 0000001101001101. A >> drops the least significiant bits, 2 states to drop 2. Then remaining binary value are then shifted by 2 and 00 is added as MSB, thus the new value for pwm is 0000000011010011

<< moves the value the other way by dropping MSB and adding 0's to the LSB

I think AWOL was referring to the stray '='

Hmmm not sure, I was looking at a different guide for a quick analog pot to PWM and copied >>=2 from there.

Seems to work anyway so I dunno what effect stray = had.

pwm = pwm >>= 2; // sets pwm to pwm that was set to itself right shifted 2 bits.

And then the compiler removes the redundant assignment ( pwm = ) in optimization.

From Arduino Reference - Arduino Reference which has links to each:

Compound Operators
%= (compound remainder)
&= (compound bitwise and)
*= (compound multiplication)
++ (increment)
+= (compound addition)
-- (decrement)
-= (compound subtraction)
/= (compound division)
^= (compound bitwise xor)
|= (compound bitwise or)