Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
7.6 kB
2
Indexable
Never
// PROGRAMMING TASK 1
#define LED_PIN 7 // Represents PB7 (Arduino pin 13)

static FILE uart00;
static unsigned int persistentValueInMemory = 0;
char convertedString[20];
char unitCodeAndTitle[] = "SEE222: Problem Solving Task - Part A";
char programName[] = "Custom Arduino Calculator";
char studentName[] = "RODRIGO LADESLAU DA CRUZ";
char studentID[] = "222165538";
char selectedCommand = 'P'; // Assigning a random character to initialize the variable that is not on the list of choices

void setup() {
  int i = 0;
  USART0_init();
  // Set pins A0 to A15 and 30 to 37 as inputs with pull-up resistors
  for(i = 0; i < 8; i++){
    pinModeInputPullup(i, 'F'); // A0 to A7
    pinModeInputPullup(i, 'K'); // A8 to A15
    pinModeInputPullup(i, 'C'); // 30 to 37
  }
  // Set pins 40 to 47 as inputs with pull-up resistors
  for(i = 0; i < 2; i++){
    pinModeInputPullup(i, 'G'); // 40 to 41
  }
  for(i = 7; i >= 2; i--){
    pinModeInputPullup(i, 'L'); // 42 to 47
  }
  // Set pin 13 as output
  DDRB |= (1 << LED_PIN);
}

void loop() {
  unsigned char value1 = 0, value2 = 0, value3 = 0, value4 = 0, value5 = 0;
  // Turn on LED on PIN 13
  PORTB |= (1 << LED_PIN); // Turn on LED on pin 13 (PB7)

  // Resquet command from external user via serial PORT
  printf("Select one option:\n A \n ! \n E \n M \n R \n C \n");
  scanf("%c", &selectedCommand);
  while((getchar()) != '\n'); // Read and discard newline. The getchar() function will read and discard characters until it encounters a newline ('\n'), effectively clearing the input buffer.

  // Turn off LED on PIN 13
  PORTB &= ~(1 << LED_PIN); // Turn off LED on pin 13 (PB7)
  printf("You selected %c \n", selectedCommand);
  _delay_ms(500);
  switch(selectedCommand){
    case 'A':
      printf("Enter Value 1:\n");
      while((getchar()) != '\n'); //  Wait until user presses Enter and clear the buffer
      printf("%d\n", PORTF); // Read Value1 from pins [A7 A6 … A1 A0] and show it in decimal on the screen
      value1 = PORTF;

      printf("Enter Value 2:\n");
      while((getchar()) != '\n'); //  Wait until user presses Enter and clear the buffer
      printf("%d\n", PORTK); // Read Value1 from pins [A15 A14 … A9 A8] and show it in decimal on the screen
      value2 = PORTK;

      printf("Enter Value 3:\n"); // 
      while((getchar()) != '\n'); // Wait until user presses Enter and clear the buffer
      printf("%d\n", reverseBits(PORTC)); // We need to be careful with this one because PC7 is the LSB in the presented logic, so we will reverse
      value3 = reverseBits(PORTC);

      printf("Enter Value 4:\n"); //
      while((getchar()) != '\n'); //  Wait until user presses Enter and clear the buffer
      value4 = (PG1 << 0) | (PG0 << 1) | (PL7 << 2) | (PL6 << 3) | (PL5 << 4) | (PL4 << 5) | (PL3 << 6) | (PL2 << 7);
      printf("%d\n", value4); // Due to the complexity, it was easier to compose the whole register corresponding operations

      do {
        printf("Enter Value 5 (between 0 and 255):\n");
        scanf("%d", &value5);
        while((getchar()) != '\n'); // Wait until user presses Enter and clear the buffer
      } while (value5 < 0 || value5 >= 256);
      printf("%d\n", value5); // Read Value5 from keyboard, show it on the screen
      dtostrf((value1 + value2 + value3 + value4 + value5)/5.0, 6, 2, convertedString);
      printf("Average: %s\n", convertedString); // Show the outcome of the average
      break;
    case '!':
      do {
        printf("Enter Value 5 (between 0 and 255):\n");
        scanf("%d", &value5);
        while((getchar()) != '\n'); // Wait until user presses Enter and clear the buffer
      } while (value5 < 0 || value5 >= 256);
      dtostrf(factorial(value5), 6, 2, convertedString);
      printf("Factorial: %s\n", convertedString); // Show the the outcome of factorial
      // The factorial of 21! overflows the 64-bit limit. So the maximum would be 20! for unsigned long long.
      break;
    case 'E':
      do {
        printf("Enter Value 5 (between 0 and 255):\n");
        scanf("%d", &value5);
        while((getchar()) != '\n'); // Wait until user presses Enter and clear the buffer
      } while (value5 < 0 || value5 >= 256);

      printf("Enter Value 2:\n");
      while((getchar()) != '\n'); //  Wait until user presses Enter and clear the buffer
      printf("%d\n", PORTK); // Read Value1 from pins [A15 A14 … A9 A8] and show it in decimal on the screen
      value2 = PORTK;
      dtostrf(power(value5, value2), 6, 2, convertedString);
      printf("Outcome of exponentiation: %s\n", convertedString); // Show the the outcome of exponentiation
      break;
    case 'M':
      do {
        printf("Enter Value 5 (between 0 and 255):\n");
        scanf("%d", &value5);
        while((getchar()) != '\n'); // Wait until user presses Enter and clear the buffer
      } while (value5 < 0 || value5 >= 256);

      persistentValueInMemory += value5;

      printf("New value stored in memory: %u\n", persistentValueInMemory); // Show the the outcome of exponentiation
      break;
    case 'R':
      printf("Current value stored in memory: %u\n", persistentValueInMemory); // Show the the outcome of exponentiation
      break;
    case 'C':
      persistentValueInMemory = 0;
      printf("Current value stored in memory: %u\n", persistentValueInMemory); // Show the the outcome of exponentiation
      break;
    default:
      // Handle unknown commands here:
      printf("Unknown command %c\n", selectedCommand);
      break;
  }
}

void USART0_init(void){
  // Initialize USART0 peripheral
  UCSR0A = 0;
  UCSR0B = (1 << TXEN0) | (1 << RXEN0);
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
  UBRR0 = 103;
  fdev_setup_stream(&uart00, TX, RX, _FDEV_SETUP_RW);
  stdin = stdout = &uart00;
}

static int RX(FILE *stream) {
  // Wait until data is received and is ready to be read from UDR0
  while ((UCSR0A & (1 << RXC0)) == 0);

  // When flag is set, read data from USART0 register and return it
  return UDR0;
}

static int TX(char TXData, FILE *stream) {
  // Wait until the transmit buffer is empty
  while ((UCSR0A & (1 << UDRE0)) == 0);

  // Write the byte to the transmit buffer
  UDR0 = TXData;
  return 0;
}

unsigned char reverseBits(unsigned char registerToReverse) {
    int numOfBits = 8;
    unsigned char reverseNum = 0;
    int i;

    for (i = 0; i < numOfBits; i++) {
        if((registerToReverse & (1 << i)))
           reverseNum |= 1 << ((numOfBits - 1) - i);
    }

    return reverseNum;
}

double factorial(int n) {
    double fact = 1;
    for(int i = 2; i <= n; i++) {
        fact *= i;
    }
    return fact;
}

unsigned long long power(unsigned char base, unsigned char exponent) {
    int result = 1;
    for(int i = 0; i < exponent; i++) {
        result *= base;
    }
    return result;
}

void pinModeInputPullup(int pin, char port){
  switch(port){
    case 'F':
      DDRF &= ~(1 << pin);
      PORTF |= (1 << pin);
      break;
    case 'K':
      DDRK &= ~(1 << pin);
      PORTK |= (1 << pin);
      break;
    case 'C':
      DDRC &= ~(1 << pin);
      PORTC |= (1 << pin);
      break;
    case 'L':
      DDRL &= ~(1 << pin);
      PORTL |= (1 << pin);
      break;
    case 'G':
      DDRG &= ~(1 << pin);
      PORTG |= (1 << pin);
      break;
    default:
      // Handle unknown ports here:
      printf("Unknown port: %c\n", port);
      break;
  }
}