1

I want to use attiny13 in my project but this program is going over 1KB

void setup()
{
  Serial.begin(9600);
  delay(2000);
  Serial.println("AT+CMGF=1");
  delay;
}
void loop()
{
  for (int i=0 ;i < 1 ;i++)
  {
    delay(1500);

    Serial.print("AT+CMGS=\"");
    Serial.print("+918269394684");
    Serial.println("\"");
    while(Serial.read()!='>');
    {
      Serial.print("22.7010709,75.9372517");
      delay(500);
      Serial.write(0x1A);
      Serial.write(0x0D);
      Serial.write(0x0A);
      delay(5000);
    }
  }
}
5

There are several problems with your program as shown that make a good answer impossible. After I list those problems, I'll then proceed to give an answer, partly good, partly bad. The good part is that the 432-bytes-of-code program shown below should send all the indicated text strings, in the proper order and separated by appropriate delays. The bad part is that it sends at 115200 bps instead of 9600. Depending on point of view, it may be good or may be bad that the code doesn't look for absence of '>' on Serial input; as I note in discussion of problems, the original code's unclear.

As promised, here are several problems with your program as shown, and how to fix them:

  • The statement delay; is a constant expression [address of the delay() function rather than a call to delay()] so take it out.

  • The statement for (int i=0 ;i < 1 ;i++) is a do-nothing so take it out.

  • The sequence while(Serial.read()!='>'); { is confusing – it compiles but isn't something a rational programmer would write – so take it out. (As written, with a semicolon directly between the right parenthesis and the left brace, it busy-waits until it reads '>' on Serial input. Then the unnecessarily-blocked block of statements within the matched braces executes one time and loop() exits its current pass. If the semicolon weren't there, the statements within the braces would execute repeatedly until a '>' appears on Serial input.)

Anyhow, with the minor fixes outlined above, and using the BasicSerial library from nerdralph's writing AVR assembler code with Arduino page, we get the following message for the program shown below.

Sketch uses 432 bytes (42%) of program storage space. Maximum is 1,024 bytes. Global variables use 68 bytes of dynamic memory.

#include <BasicSerial.h>
char *text = "AT+CMGF=1\n\0"    "AT+CMGS=\"+918269394684\"\0"
  "22.7010709,75.9372517\0" "\033\r\n";
#define send(item) while (*item) TxByte (*item++)
void setup() {
  //Serial.begin(9600);
  delay(2000);
  //Serial.write("AT+CMGF=1\n");
  send(text);
  //delay;
}
void loop() {
  char *msg = text;
  delay(1500);          // took out `for`
  //Serial.write("AT+CMGS=\"+918269394684\"");
  send(msg);
  //while(Serial.read()!='>'); {
  //Serial.write("22.7010709,75.9372517");
  send(msg);
  delay(500);
  //Serial.write("\033\r\n");
  send(msg);
  delay(5000);
  //}
}

Program Notes:

  1. The string text contains all the text from your original Serial prints and writes. With the text organized as a single string, the program only needs to set its character pointer msg once per loop, saving perhaps half a dozen bytes of code.

  2. The commented-out Serial.write statements are equivalents of your various Serial.println, Serial.print, and Serial.write statements, with adjacent strings lumped into single writes, thus for example using one write instead of three to write the Esc, CR, LF sequence just before delay(5000). Just changing those printlns, prints and writes all to writes reduces code size by about 150 bytes, which might be enough of a reduction to get you by, depending where you start from. But in my tests, substituting BasicSerial in place of Serial saves over a thousand bytes so is likely to be a requirement.

  3. You probably can modify the code in BasicSerial.S for other data rates, or perhaps can substitute one or another of the small Serial replacements listed in ernstc's Serial communication with the Tiny's webpage, to get different data rates and/or receive as well as transmit.

Edit: As Edgar Bonet noted in a comment, an ATtiny13 has 64 bytes of RAM, so the above program (using 68 bytes of RAM) will fail. RAM usage can be reduced by copying string characters individually from program memory, instead of copying the string into RAM (per Arduino default). See the following revision of the program, which also corrects a problem (leaving msg pointed at a null byte) that would keep the former program from working. Note, with these changes, we have:

Sketch uses 456 bytes (44%) of program storage space. Maximum is 1,024 bytes. Global variables use 6 bytes of dynamic memory.

#include <BasicSerial.h>
#include <avr/pgmspace.h>
const char text[] PROGMEM = "AT+CMGF=1\n\0" 
  "AT+CMGS=\"+918269394684\"\0"
  "22.7010709,75.9372517\0" "\033\r\n";
char *front = (char*)text;
#define send(item) while (pgm_read_byte(item)) TxByte (pgm_read_byte(item++))

void setup() {
  delay(2000);
  send(front);  ++front;
}
void loop() {
  char *msg = front; 
  delay(1500);
  send(msg);   ++msg;
  send(msg);   ++msg;
  delay(500);
  send(msg);
  delay(5000);
}
  • Global variables use 68 bytes of dynamic memory.” Since the ATtiny13 has only 64 bytes of RAM, you may want to put text in PROGMEM. – Edgar Bonet Feb 4 '16 at 16:32
  • Nicely optimized! But I think like better static void send(const char * &item) { while (char c = pgm_read_byte(item++)) TxByte(c); }, as it avoids all the ++front and ++msg. – Edgar Bonet Feb 5 '16 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.