Advertisement
Guest User

Untitled

a guest
Feb 4th, 2014
641
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.78 KB | None | 0 0
  1. #define F_CPU 14745600
  2. #define BAUD_PRESCALE 23
  3.  
  4. #define DAY_IN_SECONDS 86400L
  5. #define I_LAYER_COUNT 17
  6. #define J_LAYER_COUNT 16
  7. #define WEIGHT_RESOLUTION 32.0F
  8. #define BASE_ETA 0.01 * WEIGHT_RESOLUTION
  9. #define FORECAST_PERIOD 1800
  10. #define TRAINING_PERIODS 3
  11.  
  12. #include <stdio.h>
  13. #include <stdbool.h>
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include <avr/io.h>
  17. #include <avr/interrupt.h>
  18. #include <avr/sleep.h>
  19. #include <avr/wdt.h>
  20. #include <util/delay.h>
  21. #include "wti_serial.h"
  22. #include "wti_ringbuffer.h"
  23. #include "wti_switch.h"
  24.  
  25. typedef enum {SUCCESS, CRC_MISMATCH} network_restore_status;
  26.  
  27. void initializeHardware();
  28. void initializeNeuralNetwork();
  29. int8_t randInt8();
  30. float sig(float);
  31. void calculateSensorValues(float *sensors, int32_t theTime, int32_t lastCoffeeTime);
  32. void calculateHiddenLayerValues(float *hiddenNodes, float *sensors);
  33. void calculateOutput(float *output, float *hiddenNodes);
  34. float forecast(int32_t theTime, int32_t lastCoffeeTime);
  35. void train(float target, int32_t theTime, int32_t lastCoffeeTime, float eta);
  36. void randAdd(int8_t *integer, float flt);
  37. void lightLights(float forecast);
  38. void eeWrite(uint16_t*, uint8_t);
  39. uint8_t eeRead(uint16_t*);
  40. void backupNetwork();
  41. network_restore_status restoreNetwork();
  42.  
  43. static FILE serialStdout = FDEV_SETUP_STREAM(serialWrite, NULL, _FDEV_SETUP_WRITE);
  44.  
  45. volatile int32_t timerCounter;
  46. volatile int16_t forecastTimer = 10;
  47. volatile int16_t trainingTimer = 60;
  48. volatile int16_t backupTimer = 7237;
  49.  
  50. // Network Data
  51. int8_t ijMatrix[I_LAYER_COUNT][J_LAYER_COUNT];
  52. int8_t jkMatrix[J_LAYER_COUNT];
  53. int8_t jBias[J_LAYER_COUNT];
  54. int8_t kBias;
  55.  
  56. int main(void) {  
  57.   // Training Data
  58.   int32_t tLastCoffeeTimes[TRAINING_PERIODS] = {0};
  59.   int32_t tTheTimes[TRAINING_PERIODS] = {0};
  60.   int32_t lastCoffeeTime = 0;
  61.   float tTargets[TRAINING_PERIODS] = {0.1};
  62.  
  63.   initializeHardware();    
  64.  
  65.   if (restoreNetwork() != SUCCESS) {
  66.     _delay_ms(3000);
  67.     initializeNeuralNetwork();
  68.     backupNetwork();
  69.   }
  70.  
  71.   while(1) {    
  72.     wdt_reset();
  73.     if ((PINC & (1<<PINC0)) == 0) {
  74.       for (uint8_t k = 0; k < TRAINING_PERIODS; k++) {
  75.         tTargets[k] = 0.9;
  76.       }
  77.      
  78.       lastCoffeeTime = timerCounter;
  79.       printf("Button Press.\n");
  80.     }
  81.    
  82.     if (trainingTimer == 0) {
  83.       trainingTimer = FORECAST_PERIOD / TRAINING_PERIODS;
  84.  
  85.       float eta = BASE_ETA + 0.4 * WEIGHT_RESOLUTION * exp(-(double)timerCounter/(DAY_IN_SECONDS * 2));      
  86.       train(tTargets[0], tTheTimes[0], tLastCoffeeTimes[0], eta);
  87.      
  88.       for (uint8_t k = 1; k < TRAINING_PERIODS; k++) {        
  89.         tTargets[k - 1] = tTargets[k];
  90.         tTheTimes[k - 1] = tTheTimes[k];
  91.         tLastCoffeeTimes[k - 1] = tLastCoffeeTimes[k];
  92.       }
  93.      
  94.       tTargets[TRAINING_PERIODS - 1] = 0.1;
  95.       tTheTimes[TRAINING_PERIODS - 1] = timerCounter;
  96.       tLastCoffeeTimes[TRAINING_PERIODS - 1] = lastCoffeeTime;  
  97.      
  98.       printf("\nijMatrix:\n");
  99.       for (uint8_t i = 0; i < I_LAYER_COUNT; i++) {
  100.         for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  101.           printf("%i, ", ijMatrix[i][j]);
  102.         }
  103.         printf("\n");
  104.       }  
  105.      
  106.       printf("\njBiases:\n");
  107.       for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  108.         printf("%i, ", jBias[j]);
  109.       }
  110.       printf("\n");
  111.      
  112.       printf("\njkMatrix:\n");      
  113.       for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  114.         printf("%i, ", jkMatrix[j]);
  115.       }
  116.       printf("\n\nkBias: %i\n\n", kBias);      
  117.     }
  118.    
  119.     if (forecastTimer == 0) {
  120.       float currentForecast = forecast(timerCounter, lastCoffeeTime);            
  121.       forecastTimer = 30;
  122.       printf("Current forecast: %f at %li, %li\n", currentForecast, (timerCounter % 86400), (lastCoffeeTime % 86400));
  123.       lightLights(currentForecast);
  124.     }
  125.  
  126.     if (backupTimer == 0) {
  127.       backupTimer = 7200;
  128.       backupNetwork();
  129.     }
  130.    
  131.     _delay_ms(100);
  132.   }          
  133. }
  134.  
  135. void initializeHardware() {
  136.   cli();
  137.   stdout = &serialStdout;
  138.  
  139.   //Initialize USART, its buffer and TWI
  140.   usartInit(BAUD_PRESCALE);
  141.   rbInit(&serialTxBuffer);
  142.  
  143.   // turn off Timer/Counter2, Timer/Counter0, Serial Peripheral Interface, ADC
  144.   PRR = (1<<PRTIM2) | (1<<PRTIM0) | (1<<PRSPI) | (1<<PRADC);
  145.  
  146.   MCUSR &= ~(1<<WDRF); //Disable System Reset Flag in MCU Status Register
  147.   wdt_reset(); //C.f. doc note on page 53.
  148.   //"The Watchdog Timer should be reset before any change of the WDP bits"
  149.   WDTCSR = (1<<WDCE) | (1<<WDE); //Write logic one to WDCE and WDE bits of WDTCSR simultaneously
  150.   //to begin wd config procedure
  151.   WDTCSR = (1<<WDP3) | (1<<WDP0);  //  Set WD prescaler for 8.0 seconds
  152.  
  153.   OCR1A  = 0x3840; // Compare match at 1.00 seconds
  154.   TCCR1B = (1<<CS12) | (1<<CS10);
  155.   TIMSK1 = (1<<OCIE1A) | (1<<TOIE1);
  156.  
  157.   PORTC = (1<<PORTC0) | (1<<PORTC1) | (1<<PORTC2) | (1<<PORTC3);
  158.   DDRC = (1<<PORTC1) | (1<<PORTC2) | (1<<PORTC3);
  159.  
  160.   // Set up EEPROM
  161.   EECR = 0x00; // Mode = atomic, Interrupt = disabled
  162.   sei();
  163. }
  164.  
  165. void initializeNeuralNetwork() {
  166.   srandom(252);  
  167.    
  168.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  169.     for (int i = 0; i < I_LAYER_COUNT; i++) {
  170.       ijMatrix[i][j] = randInt8() / 4;
  171.     }
  172.   }
  173.  
  174.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  175.     jkMatrix[j] = randInt8() / 4;
  176.     jBias[j] = randInt8() / 4;
  177.   }
  178.  
  179.   kBias = randInt8() / 4;
  180.  
  181.   for (int32_t tTime = 0; tTime < 86400 * 6; tTime += 60 * 5) {
  182.     train(0.3, tTime, tTime - 3600, 0.1 * WEIGHT_RESOLUTION);
  183.   }
  184. }
  185.  
  186. int8_t randInt8() {
  187.   return (rand() % 128) - 64;
  188. }
  189.  
  190. float readClockSensorSin(int32_t theTime, int32_t period) {
  191.   return sin(2 * M_PI * (double)(theTime % period) / period);
  192. }
  193.  
  194. float readClockSensorCos(int32_t theTime, int32_t period) {
  195.   return cos(2 * M_PI * (double)(theTime % period) / period);
  196. }
  197.  
  198. float sig(float x) {
  199.   return 1 / (1 + exp(-x));
  200. }
  201.  
  202. void calculateSensorValues(float *sensors, int32_t theTime, int32_t lastCoffeeTime) {
  203.   sensors[0] = readClockSensorSin(theTime, DAY_IN_SECONDS);
  204.   sensors[1] = readClockSensorCos(theTime, DAY_IN_SECONDS);
  205.  
  206.   sensors[2] = readClockSensorSin(theTime, DAY_IN_SECONDS/2);
  207.   sensors[3] = readClockSensorCos(theTime, DAY_IN_SECONDS/2);
  208.  
  209.   sensors[4] = readClockSensorSin(theTime, DAY_IN_SECONDS/3);
  210.   sensors[5] = readClockSensorCos(theTime, DAY_IN_SECONDS/3);
  211.  
  212.   sensors[6] = readClockSensorSin(theTime, DAY_IN_SECONDS/4);
  213.   sensors[7] = readClockSensorCos(theTime, DAY_IN_SECONDS/4);
  214.  
  215.   sensors[8] = readClockSensorSin(theTime, DAY_IN_SECONDS/6);
  216.   sensors[9] = readClockSensorCos(theTime, DAY_IN_SECONDS/6);
  217.  
  218.   sensors[10] = readClockSensorSin(theTime, DAY_IN_SECONDS/8);
  219.   sensors[11] = readClockSensorCos(theTime, DAY_IN_SECONDS/8);
  220.  
  221.   sensors[12] = readClockSensorSin(theTime, DAY_IN_SECONDS/12);
  222.   sensors[13] = readClockSensorCos(theTime, DAY_IN_SECONDS/12);
  223.  
  224.   sensors[14] = exp(-(double)(theTime - lastCoffeeTime) / ((double)60L * 60 * 2));
  225.   sensors[15] = exp(-(double)(theTime - lastCoffeeTime) / ((double)60L * 60 * 8));
  226.   sensors[16] = exp(-(double)(theTime - lastCoffeeTime) / ((double)60L * 60 * 24));
  227. }
  228.  
  229. void calculateHiddenLayerValues(float *hiddenNodes, float *sensors) {
  230.   for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  231.     hiddenNodes[j] = (float)jBias[j] / WEIGHT_RESOLUTION;
  232.    
  233.     for (uint8_t i = 0; i < I_LAYER_COUNT; i++) {
  234.       hiddenNodes[j] += sensors[i] * (float)ijMatrix[i][j] / WEIGHT_RESOLUTION;
  235.     }
  236.    
  237.     hiddenNodes[j] = sig(hiddenNodes[j]);
  238.   }
  239. }
  240.  
  241. void calculateOutput(float *output, float *hiddenNodes) {
  242.   *output = (float)kBias / WEIGHT_RESOLUTION;
  243.   for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  244.     *output += hiddenNodes[j] * (float)jkMatrix[j] / WEIGHT_RESOLUTION;
  245.   }
  246.   *output = sig(*output);
  247. }
  248.  
  249. float forecast(int32_t theTime, int32_t lastCoffeeTime) {
  250.   float sensors[I_LAYER_COUNT];
  251.   float hiddenNodes[J_LAYER_COUNT];
  252.   float output;
  253.  
  254.   calculateSensorValues(sensors, theTime, lastCoffeeTime);
  255.   calculateHiddenLayerValues(hiddenNodes, sensors);
  256.   calculateOutput(&output, hiddenNodes);  
  257.  
  258.   return output;  
  259. }
  260.  
  261. void train (float target, int32_t theTime, int32_t lastCoffeeTime, float eta) {
  262.   float sensors[I_LAYER_COUNT];
  263.   float hiddenNodes[J_LAYER_COUNT];
  264.   float deltaJs[J_LAYER_COUNT];
  265.   float output, deltaK;
  266.    
  267.   calculateSensorValues(sensors, theTime, lastCoffeeTime);
  268.   calculateHiddenLayerValues(hiddenNodes, sensors);
  269.   calculateOutput(&output, hiddenNodes);
  270.  
  271.   printf("\nTraining:\n");
  272.   printf("Target: %f, Output: %f\n", target, output);
  273.  
  274.   deltaK = output * (1 - output) * (output - target);
  275.  
  276.   for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  277.     deltaJs[j] = hiddenNodes[j] * (1 - hiddenNodes[j]) * deltaK * jkMatrix[j];
  278.   }
  279.  
  280.   for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  281.     for (uint8_t i = 0; i < I_LAYER_COUNT; i++) {
  282.       randAdd(&ijMatrix[i][j], -eta * deltaJs[j] * sensors[i]);
  283.     }
  284.   }
  285.  
  286.   for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  287.     randAdd(&jBias[j], -eta * deltaJs[j]);
  288.   }
  289.  
  290.   for (uint8_t j = 0; j < J_LAYER_COUNT; j++) {
  291.     randAdd(&jkMatrix[j], -eta * deltaK * hiddenNodes[j]);
  292.   }
  293.  
  294.   randAdd(&kBias, -eta * deltaK);
  295.  
  296.   calculateSensorValues(sensors, theTime, lastCoffeeTime);
  297.   calculateHiddenLayerValues(hiddenNodes, sensors);
  298.   calculateOutput(&output, hiddenNodes);
  299.   printf("\nUpdated Output: %f\n", output);
  300. }
  301.  
  302. void randAdd(int8_t *integer, float flt) {
  303.   int8_t sign;
  304.   int16_t result = *integer;
  305.  
  306.   if (flt < 0) {
  307.     flt = -flt;
  308.     sign = -1;
  309.   } else {
  310.     sign = 1;    
  311.   }
  312.  
  313.   while (flt > 1) {
  314.     flt--;
  315.     result += sign;
  316.     printf("|");
  317.   }
  318.    
  319.   if (flt * 1000 >= rand() % 1000) {
  320.     printf(".");
  321.     result += sign;
  322.   }
  323.  
  324.   if (result > 127) {
  325.     result = 127;  
  326.   } else if (result < -128) {
  327.     result = -128;
  328.   }
  329.  
  330.   *integer = (int8_t)result;
  331. }
  332.  
  333. void lightLights(float forecast) {
  334.   PORTC &= ~((1<<PORTC1) | (1<<PORTC2) | (1<<PORTC3));
  335.  
  336.   if (forecast >= 0.05 && 0.15 > forecast) {
  337.     PORTC |= (1 << PORTC1);
  338.   }
  339.  
  340.   if (forecast >= 0.15 && 0.25 > forecast) {
  341.     PORTC |= (1 << PORTC2);
  342.   }
  343.  
  344.   if (forecast >= 0.25) {
  345.     PORTC |= (1 << PORTC3);
  346.   }
  347. }
  348.  
  349. ISR(TIMER1_COMPA_vect) {
  350.   TCNT1 = 0x0000;
  351.   timerCounter++;
  352.  
  353.   if (trainingTimer > 0) {
  354.     trainingTimer--;
  355.   }
  356.  
  357.   if (forecastTimer > 0) {
  358.     forecastTimer--;
  359.   }
  360.  
  361.   if (backupTimer > 0) {
  362.     backupTimer--;
  363.   }
  364. }
  365.  
  366. void eeWrite(uint16_t *uiAddress, uint8_t ucData) {
  367.   cli();
  368.   /* Wait for completion of previous write */
  369.   while(EECR & (1<<EEPE)) ;
  370.  
  371.   /* Set up address and Data Registers */
  372.   EEAR = *uiAddress;
  373.   EEDR = ucData;
  374.   /* Write logical one to EEMPE */
  375.   EECR |= (1<<EEMPE);
  376.   /* Start eeprom write by setting EEPE */
  377.   EECR |= (1<<EEPE);
  378.   (*uiAddress)++;
  379.   sei();
  380. }
  381.  
  382. uint8_t eeRead(uint16_t *uiAddress) {
  383.   /* Wait for completion of previous write */
  384.   while(EECR & (1<<EEPE)) ;
  385.   /* Set up address register */
  386.   EEAR = *uiAddress;
  387.   /* Start eeprom read by writing EERE */
  388.   EECR |= (1<<EERE);
  389.   (*uiAddress)++;
  390.   /* Return data from Data Register */
  391.   return EEDR;
  392. }
  393.  
  394. uint16_t crc16(uint16_t crc, uint8_t data) {
  395.   crc = crc ^ (uint16_t)data;
  396.  
  397.   for (uint8_t i = 8; i > 0; i--) {
  398.     if (crc & 0x0001) {
  399.       crc = (crc >> 1)^0x8408;
  400.     } else {
  401.       crc >>= 1;
  402.     }
  403.   }
  404.  
  405.   return crc;  
  406. }
  407.  
  408. void backupNetwork() {
  409.   uint16_t eeAddress = 0;
  410.   uint16_t crc = 0xFFFF;
  411.  
  412.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  413.     for (int i = 0; i < I_LAYER_COUNT; i++) {
  414.       eeWrite(&eeAddress, ijMatrix[i][j]);
  415.       crc = crc16(crc, ijMatrix[i][j]);
  416.     }
  417.   }
  418.  
  419.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  420.     eeWrite(&eeAddress, jkMatrix[j]);
  421.     crc = crc16(crc, jkMatrix[j]);
  422.   }
  423.  
  424.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  425.     eeWrite(&eeAddress, jBias[j]);
  426.     crc = crc16(crc, jBias[j]);
  427.   }
  428.  
  429.   eeWrite(&eeAddress, kBias);
  430.   crc = crc16(crc, kBias);
  431.  
  432.   printf("New CRC: %x\n", crc);
  433.   eeWrite(&eeAddress, (crc>>8));
  434.   eeWrite(&eeAddress, crc);
  435. }
  436.  
  437. network_restore_status restoreNetwork() {
  438.   uint16_t eeAddress = 0;
  439.   uint16_t crc = 0xFFFF;
  440.   uint16_t storedCrc = 0;
  441.  
  442.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  443.     for (int i = 0; i < I_LAYER_COUNT; i++) {
  444.       ijMatrix[i][j] = eeRead(&eeAddress);
  445.       crc = crc16(crc, ijMatrix[i][j]);
  446.     }
  447.   }  
  448.  
  449.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  450.     jkMatrix[j] = eeRead(&eeAddress);
  451.     crc = crc16(crc, jkMatrix[j]);
  452.   }
  453.  
  454.   for (int j = 0; j < J_LAYER_COUNT; j++) {
  455.     jBias[j] = eeRead(&eeAddress);
  456.     crc = crc16(crc, jBias[j]);
  457.   }
  458.  
  459.   kBias = eeRead(&eeAddress);
  460.   crc = crc16(crc, kBias);
  461.  
  462.   storedCrc |= (uint16_t)eeRead(&eeAddress);
  463.   storedCrc <<= 8;
  464.   storedCrc |= (uint16_t)eeRead(&eeAddress);
  465.   if (crc != storedCrc) {
  466.     printf("Restore Failed. %x != %x\n", crc, storedCrc);
  467.     return CRC_MISMATCH;
  468.   } else {
  469.     printf("Network restored successfully.\n");
  470.     return SUCCESS;
  471.   }
  472. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement