Need help with code - Page 1
Forum section: electronics / projects

author: bigone5500
author_rank: Contributor
timestamp: June 03, 2015, 11:46:52 am
content: I found this code online and want to try to build this clock. However, when I try to compile the code in arduino, I get errors. One is on line 7 and says 'initializer-string for array of chars is too long [-fpermissive]. I can change the 3 to a 6 and it goes past that. I then get an error on line 61 that says 'PORTA' was not declared in this scope. I'm thinking that I need to do something with a library but not sure.Code:#include<avr/io.h>#include<stdio.h>#define F_CPU 8000000UL#include<util/delay.h>#include<avr/interrupt.h>char value;char days={"SUN","MON","TUE","WED","THU","FRI","SAT"};char position={0x00,0x88,0x85,0x8d,0xc5,0xc8,0xcb};int i,time;int j=0;void i2c_init(){TWSR=0x00;TWBR=0x47;TWCR=0x04;}void i2c_start(){TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);while((TWCR &(1<<TWINT))==0);}void i2c_stop(){TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);}void i2c_write(char data){TWDR=data;TWCR=(1<<TWINT)|(1<<TWEN);while((TWCR &(1<<TWINT))==0);}unsigned char i2c_read(){TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);while(!(TWCR &(1<<TWINT)));return TWDR;}void data(char *txt){PORTB|=(1<<1);while(*txt!='\0'){PORTA=*txt++;PORTB|=(1<<0);_delay_ms(1);PORTB&=~(1<<0);_delay_ms(1);}}void cmd(char comm){PORTA=comm;PORTB&=~(1<<1);PORTB|=(1<<0);_delay_ms(1);PORTB&=~(1<<0);_delay_ms(1);}void time_set(void){i2c_init();i2c_start();i2c_write(0xD0);i2c_write(0x00);i2c_write(0x00);i2c_write(0x00);i2c_write(0x16);i2c_write(0x00);i2c_write(0x31);i2c_write(0x05);i2c_write(0x15);i2c_stop();_delay_ms(2);}void time_write(){if((i==2)|(i==4)|(i==5)){cmd(position);data(value);data("-");}else if(i==3){cmd(position);data(&days);}else if(i==7){}else{cmd(position);data(value);}}int main(void){DDRB=0x03;DDRA=0xff;DDRC=0x00;cmd(0x38);cmd(0x0c);cmd(0x01);cmd(0x80);data("TIME:");cmd(0xc0);data("DATE:");time_set();j=0;while(1){i2c_start();i2c_write(0xD0);i2c_write(0x01);i2c_stop();_delay_ms(2);i2c_start();i2c_write(0xD1);for(i=1;i<=7;i++){time=i2c_read();sprintf(&value,"%x",time&0xF0);sprintf(&value,"%x",time&0x0F);time_write();}i2c_stop();_delay_ms(2);}return 0;}I played around with and found out that if I leave the '3' and change the double quotes to single, I do not get the first error.I still am trying to figure out how to get around the 'PORTA' was not declared in this scope issue.

author: madires
author_rank: Super Contributor
timestamp: June 03, 2015, 12:10:13 pm
content: The source code is for a raw ATmega not an arduino-nized one. If you want to use an Arduino you would have to adapt the code.

author: SL4P
author_rank: Super Contributor
timestamp: June 03, 2015, 01:27:17 pm
content: If I'm correct "string-literals" always occupy n+1 bytes to accommodate the trailing null terminator...But 'character-literals' only require the nominated number of characters -- assuming your software will look after the string length.I don't think PORTA is defined (like PIC) in Arduino-speak... you need to check the name used, or create your own reassignment of the port direction and I/o registers.

author: pyrohaz
author_rank: Regular Contributor
timestamp: June 03, 2015, 01:35:04 pm
content: Quote from: SL4P on June 03, 2015, 01:27:17 pmI think that's the problem, the "days" array is declared as 7x3 where they should be 7x4 to include the null terminator. In computer terms, the string would actually be: 'S','U','N','\0' where '\0' is the null terminator.Change your days array from:days to daysYeh, PortA doesn't exist on an Arduino. This page is really useful for giving a definition of what pin maps to what port:http://www.arduino.cc/en/Reference/PortManipulation

author: SL4P
author_rank: Super Contributor
timestamp: June 03, 2015, 09:27:54 pm
content: BTW Just to add... To save 'ROM', you can keep your char-byte arrays, but only if your days are ALL going to remainexactlythree chars or are filled to three chars, then your code can just processexactly3 chars, and not be looking for the terminating null.This is relevant sometimes when your output string mustcontainnulls!

author: bigone5500
author_rank: Contributor
timestamp: June 04, 2015, 12:15:41 am
content: Thanks for the help. I changed the 3 to a 4 and it liked it. I then changed PORTA to PORTC and it liked it as well. I then compiled again and got an error that when I changed DDRA to DDCD it also liked it. The code then compiled successfully.I will keep this thread up to date with progress.Thanks again.

author: bson
author_rank: Unknown
timestamp: June 04, 2015, 12:44:16 am
content: You should declare your constant arrays "const", or they will be put in RAM and initialized from ROM.

author: oPossum
author_rank: Super Contributor
timestamp: June 04, 2015, 03:23:33 am
content: Using const on AVR will not put it in flash. AVR is strict Harvard. __attribute__((progmem)) will put variable in program memory (flash). They must be accessed with special functions - pointers will not work.

author: bson
author_rank: Unknown
timestamp: June 04, 2015, 03:53:35 am
content: That's terrible. Use a different processor that can keep tables and data in flash and forget AVR ever existed.

author: Jeroen3
author_rank: Super Contributor
timestamp: June 04, 2015, 07:34:19 am
content: This is the old fashioned way. Nowadays eveybody* uses 1 linear address space, because its easier work with, obviously.But an AVR should still be capable of the requested functionality. Just a bit slower.http://www.nongnu.org/avr-libc/user-manual/pgmspace.html