diff --git a/linear_pendulum_2009/avr/compile.sh b/linear_pendulum_2009/avr/compile.sh
index 2fdb97c3223e09e8343c5c6d0d78ce3c3dfc777d..1ad797813b1ad18a20d7909948f27d4fab3eda9c 100755
--- a/linear_pendulum_2009/avr/compile.sh
+++ b/linear_pendulum_2009/avr/compile.sh
@@ -1 +1 @@
-avr-gcc -mmcu=atmega16 -g -Wall -o current_control current_control.c
\ No newline at end of file
+avr-gcc -mmcu=atmega16 -g -Wall -o current_control_final current_control_final.c
\ No newline at end of file
diff --git a/linear_pendulum_2009/avr/compileUpload.sh b/linear_pendulum_2009/avr/compileUpload.sh
index e97cfdfa62c342c42bb1305d2a7bf9a7c07d00fd..56e4b6568e3b8d69ae00125146362a087fd9c16d 100755
--- a/linear_pendulum_2009/avr/compileUpload.sh
+++ b/linear_pendulum_2009/avr/compileUpload.sh
@@ -1,3 +1,3 @@
-avr-gcc -mmcu=atmega16 -g -Wall -o current_control current_control.c
-avr-objcopy -Osrec current_control current_control.sr
-uisp -dprog=stk200 --erase --upload if=current_control.sr
\ No newline at end of file
+avr-gcc -mmcu=atmega16 -g -Wall -o current_control_final current_control_final.c
+avr-objcopy -Osrec current_control_final current_control_final.sr
+uisp -dprog=stk200 --erase --upload if=current_control_final.sr
\ No newline at end of file
diff --git a/linear_pendulum_2009/avr/current_control.c b/linear_pendulum_2009/avr/current_control.c
index ac8d49b1b6a6a41a1f2b0bb083d8eeb65acf118d..adb0f97160f8068472aec7055d75f8bf6c3d0977 100644
--- a/linear_pendulum_2009/avr/current_control.c
+++ b/linear_pendulum_2009/avr/current_control.c
@@ -9,7 +9,6 @@
 
 *********************************************/
 
-//#include <math.h>		//Only include if sin will be used, takes up memory!
 #include <avr/io.h>
 #include <avr/signal.h>
 #include <avr/interrupt.h>
@@ -17,7 +16,7 @@
 
 
 // reference generation variables
-volatile int16_t ref = 200;
+volatile int16_t ref = 100;
 volatile int16_t refCount = 0;
 volatile int8_t refFlag = 0;
 
@@ -54,14 +53,6 @@ volatile int16_t temp;
 volatile int8_t pwmCycles = 0;
 
 
-/* Routine used to set the red LED */
-void setLED(uint8_t on)
-{
-  if (on) PORTB &= 0x7f;	//Turn on
-  else PORTB |= 0x80;	//Turn off
-}
-
-
 /* Routine used to transmit bytes on the serial port */
 static void putchar(unsigned char ch)
 {
@@ -141,7 +132,6 @@ SIGNAL(SIG_OUTPUT_COMPARE2) {
   //control, since negative measurements
   e = ref+y; //e 9 frac bits
   
-  
   //v = (int16_t)((K*e+I+64)>>7);
   v = (int16_t)(((K*e+64)>>7)+(temp>>4));
   //saturation and update integral part of ctrl
@@ -166,7 +156,6 @@ SIGNAL(SIG_OUTPUT_COMPARE2) {
   // write output, inverting mode means set pwm to 127-ctrl_out
   
   
-  
   // Original styrning med 7 bitar + direction
   u = (v+2)>>2; //7 frac bits to pwm 
   
@@ -210,28 +199,28 @@ SIGNAL(SIG_OUTPUT_COMPARE2) {
 
 /* reference square- or triangle wave generator with timer 0 */
 SIGNAL(SIG_OVERFLOW0) {
-  int8_t rectangle = 0;
+  int8_t rectangle = 1;
   refCount++;
   if (rectangle == 1) {
     if (refFlag == 0) {
-      if (refCount == 10) {
+      if (refCount == 20) {
 	refFlag = 1;
 	ref = -ref;
 	refCount = 0;
       }
     } else {
-      if (refCount == 20) {
+      if (refCount == 40) {
 	ref = -ref;
 	refCount = 0;
       }
     }
   } else {
-    if (refCount <= 40) {  // ref
-      ref -= 10;
+    if (refCount <= 200) {  // ref
+      ref -= 1;
     } else {
-      ref += 10;
+      ref += 1;
     }
-    if (refCount == 80) { // ref*2
+    if (refCount == 400) { // ref*2
       refCount = 0;
     }
   }
@@ -244,11 +233,8 @@ int main()
   int i,j;
   
   //Port directions
-  outp(0x80,PORTB); // LED off
-  outp(0x80,DDRB);  // output on LED
   outp(0x08,PORTC); // pull up on overtemp signals
   outp(0xa0,DDRC);  // output on dir and brake
-  outp(0x80,PORTD); // pull up on reset switch
   outp(0x10,DDRD);  // output on pwm for motor 1
   
   outp(0x10,DDRA);  // test pin output
diff --git a/linear_pendulum_2009/avr/current_control_final.c b/linear_pendulum_2009/avr/current_control_final.c
new file mode 100644
index 0000000000000000000000000000000000000000..5d52f9a51db1ff927866e92d0d6738d90a69e9ac
--- /dev/null
+++ b/linear_pendulum_2009/avr/current_control_final.c
@@ -0,0 +1,169 @@
+#include <avr/twi.h>
+#include <avr/io.h>
+#include <avr/signal.h>
+#include <avr/interrupt.h>
+#include <inttypes.h>
+
+
+// control variables
+volatile int16_t ref=0;
+volatile unsigned char lbyte,hbyte;  
+volatile int16_t y;
+volatile uint8_t low, high;
+volatile int16_t e = 0;
+volatile int16_t v = 0;
+volatile int16_t I = 0;
+volatile int16_t u = 0;
+volatile int16_t K = 74; // 7 frac bits
+volatile int16_t Ke = 26; //7 frac bits, K*h/Ti
+volatile int16_t Ksat = 44; // 7 frac bits, h/Tr
+
+
+// logging variables
+#define log_len 100
+volatile int16_t ctrl_log[log_len];
+volatile int16_t error_log[log_len];
+volatile int32_t I_log[log_len];
+volatile int16_t skipSamples = 1000;
+volatile int16_t countSamples = 0;
+volatile int16_t jj=0;
+volatile int8_t stop = 0;
+
+// twi variables
+volatile int16_t status;
+
+
+/* Interrupt service routine for handling incoming bytes on the serial port 
+ might be needed to catch incoming bytes */
+SIGNAL(SIG_UART_RECV){}
+
+
+/* Timer 1 compare match, start AD-conversion
+ * Additional changes: Dont use free running AD-conversion
+ *                     Enable overflow interrupts timer1
+ */
+SIGNAL(SIG_OUTPUT_COMPARE2) {
+  // Start AD conversion
+  ADCSRA |= BV(ADSC);
+  
+  PORTB |= 0x40;	//Turn on calculation timer
+    
+  // Read input
+  low = inp(ADCL);
+  high = inp(ADCH);
+  y =  ((high<<8) | low) - 512; //y 9 frac bits
+  
+  //control, since negative measurements
+  e = ref+y; //e 9 frac bits
+  
+  //v = (int16_t)((K*e+I+64)>>7);
+  v = (int16_t)(((K*e+64)>>7)+(I>>4));
+  //saturation and update integral part of ctrl
+  if (v > 511) {
+    I = I + (((Ke*e) + (Ksat)*(511-v))>>3);
+  } else if (v < -512) {
+    I = I + (((Ke*e) + (Ksat)*(-512-v))>>3);
+  } else {
+    I = I + ((Ke*e)>>3);
+  }
+  
+  // Original styrning med 7 bitar + direction
+  u = (v+2)>>2; //7 frac bits to pwm 
+  
+  if (u > 127) {
+    u = 127;
+  } else if (u < -128) {
+    u = -128;
+  }
+  //u = 0;
+  // set pwm switching time
+  if (u < 0) {
+    PORTC |= 0x80;
+    OCR1BL = (unsigned char) (128-(-u));
+  } else {
+    PORTC = (PORTC & 0x7F);
+    OCR1BL = (unsigned char) (127-u);
+  }
+
+  // TWI-communication (need status == 0x60?)
+  if ((BV(TWINT)&inp(TWCR))) {
+    status = (inp(TWSR)&0xf8);
+    if (status == 0x80) {
+      ref = (int16_t)((int8_t)(inp(TWDR))); // read reference
+      ref = ref << 2;  // shifted 2 steps for 10 bits for reference
+    } 
+    else {
+    }
+    outp(BV(TWINT)|BV(TWEN)|BV(TWEA),TWCR);
+  }
+
+  PORTB &= 0xbf;	//Turn off calculation timer  
+
+}
+
+
+int main()
+{
+  cli();
+  
+  //Port directions
+  outp(0x08,PORTC); // pull up on overtemp signals
+  outp(0xa0,DDRC);  // output on dir and brake
+  outp(0x10,DDRD);  // output on pwm for motor 1
+  
+  outp(0x40,DDRB);  // output on timer calculation pin
+
+  outp(0x10,DDRA);  // test pin output
+
+  /* Timer section */
+  // Enable timer2 compare match interrupts
+  outp(BV(OCIE2),TIMSK);
+  
+  // Timer 1, fast PWM no prescaling (inverting mode (start low, switch to high))
+  outp(BV(COM1A1)|BV(COM1B1)|BV(COM1A0)|BV(COM1B0)|BV(WGM11)|BV(WGM10),TCCR1A);
+  outp(BV(CS10)|BV(WGM13)|BV(WGM12),TCCR1B);
+  
+  // Reset Timer1 and set TOP-value to 128 (means 7-bit pwm-signal-> h_pwm=8.61 micros)
+  outp(0x00,OCR1AH);
+  outp(0x7f,OCR1AL);
+  outp(0x00,TCNT1H);
+  outp(0x00,TCNT1L);
+  outp(0x00,OCR1BH);
+  outp(0x7f,OCR1BL); // to not start motor-rotation before control
+
+  
+  /* Timer 2, 4 times pwm-period, for control sampling, prescaler 8 */
+  outp(BV(WGM21)|BV(CS21),TCCR2);
+  outp(0x3f,OCR2);
+  /* Reset timer 2 */
+  outp(0,TCNT2);
+  
+  //Serial communication
+  outp(0x00, UCSRA);	// USART:
+  outp(0x98, UCSRB);	// USART: RxIntEnable|RxEnable|TxEnable
+  outp(0x86, UCSRC);	// USART: 8bit, no parity
+  outp(0x00, UBRRH);	// USART: 115200 @ 14.7456MHz
+  outp(7,UBRRL);	// USART: 115200 @ 14.7456MHz
+  
+
+  /* AREF (AREF is 5V) pin external capacitor, MUX0 for current */
+  outp(BV(REFS0)|BV(MUX0),ADMUX); 	
+  
+  // Enable ADC, start first conversion, prescaler 32, not free running mode
+  outp(BV(ADEN)|BV(ADSC)|BV(ADPS2)|BV(ADPS0),ADCSRA);
+
+
+  // Initialize TWI
+  outp(0x02,TWBR);  // set SCL-frequency CPU-freq/(16+2*2)
+  outp(0x02,TWAR);  // slave address
+  outp(BV(TWEA)|BV(TWEN),TWCR); // enable TWI, enable ACK
+
+
+
+
+  //Enable interrupts
+  sei();
+
+  // loop
+  while (1) {}
+}