[u8glib oscilloscope] code size reduce

Help me to reduce sketch size, for uploading on atmega8 (with bootloader).
I have read lot of posts on this forum, and changed all like : font, variables, port manipulating. But code still big. Maybe someone can add something especially for MY code. Thanks.

/*
    arduino数字示波器
    作者:�ntwhq@tom.com
    2013 08
 */
#include <U8glib.h> //声明库
U8GLIB_PCD8544 u8g(7, 5, 6);
const int Input = A0;  //声明输入引脚
const int Key_add = 8;  //声明按钮引脚
const int Key_sub = 9;
const int Key_hold = 10;
int x, y; //声明坐标
int i, i1, i2, V_min, V_max, V_mid, t, sta, Key = 1, hold = 0;
long Freq;
float Vpp;
int Y[96]; //声明信号值储存数组
int Buffer[192];

void setup( )
{
  pinMode(Key_add, INPUT);
  digitalWrite(Key_add, HIGH);
  pinMode(Key_sub, INPUT);
  digitalWrite(Key_sub, HIGH);
  pinMode(Key_hold, INPUT);
  digitalWrite(Key_hold, HIGH);
  ADMUX = 0x60;
  ADCSRA = 0xe2;
  u8g.setFont(u8g_font_micro);
}

void loop( )
{
  sample( );
  Measure( );
  Transform( );
  Key_scan( );
  if (hold == 0)
  {
    u8g.firstPage( );
    do
    {
      draw( );
    }
    while ( u8g.nextPage( ));
  }
}

void sample( )
{ for (i = 0; i < 192; i++)
  {
    Buffer[i] = ADCH;
    switch (Key)
    {
      case 1:
        break;
      case 2:
        delayMicroseconds(4);
        break;
      case 3:
        delayMicroseconds(10);
        break;
      case 4:
        delayMicroseconds(23);
        break;
      case 5:
        delayMicroseconds(60);
        break;
      case 6:
        delayMicroseconds(123);
        break;
      case 7:
        delayMicroseconds(248);
        break;
      case 8:
        delayMicroseconds(623);
        break;
      case 9:
        delayMicroseconds(1247);
        break;
      default: break;
    }
  }
}

void Measure()
{
  V_max = Buffer[0];
  V_min = Buffer[0];
  for (i = 0; i < 192; i++)
  {
    if (Buffer[i] > V_max)
      V_max = Buffer[i];
    if (Buffer[i] < V_min)
      V_min = Buffer[i];
  }
  V_mid = (V_max + V_min) / 2;
  Vpp = (V_max - V_min) * 50.0 / 255;
  for (i = 0; i < 97; i++)
  {
    if (Buffer[i] < V_mid && Buffer[i + 1] >= V_mid)
    {
      i1 = i;
      break;
    }
  }
  for (i = i1 + 1; i < 98 + i1; i++)
  {
    if (Buffer[i] < V_mid && Buffer[i + 1] >= V_mid)
    {
      i2 = i;
      break;
    }
  }
  t = i2 - i1;
  if (t > 0)
    Freq = 8000 / t;
  else
    Freq = 0;
}

void Transform( )
{
  for (sta = 0; sta < 96; sta++)
  {
    if (Buffer[sta] < 128 && Buffer[sta + 2] > 128)
      break;
  }
  for (i = 0; i < 96; i++)
    Y[i] =  63 - (Buffer[i + sta] >> 2);
}

void draw( )
{
  for (x = 0; x < 60; x++)
    u8g.drawLine(x, Y[x], x, Y[x + 1]); //画线

  //画边框
//  u8g.drawFrame(0, 0, 60, 48);
  // 画坐标轴
  u8g.drawLine(30, 0, 30, 48);
  u8g.drawLine(0, 24, 60, 24);
  for (x = 0; x < 60; x += 6)
    u8g.drawLine(x, 23, x, 25);
  for (y = 0; y < 48; y += 6)
    u8g.drawLine(29, y, 31, y);
  //画网格
  for (x = 6; x < 60; x += 6)
  {
    for (y = 6; y < 48; y += 6)
      u8g.drawPixel(x, y);
  }
  //显示参数
  u8g.drawStr(62, 6, "MS");
//  u8g.drawStr(62, 18, "V");
//  u8g.drawStr(62, 24, "0.324");
  u8g.drawStr(62, 30, "Vpp");
  u8g.setPrintPos( 62, 36);
  u8g.print(Vpp);
  u8g.drawStr(78, 36, "V");
  u8g.drawStr(62, 42, "F(HZ)");
  switch (Key)
  {
    case  1:
      u8g.drawStr(62, 12, "0.02");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq * 50);
      break;
    case  2:
      u8g.drawStr(62, 12, "0.05");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq * 20);
      break;
    case  3:
      u8g.drawStr(62, 12, " 0.1");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq * 10);
      break;
    case  4:
      u8g.drawStr(62, 12, " 0.2");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq * 5);
      break;
    case  5:
      u8g.drawStr(62, 12, " 0.5");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq * 2);
      break;
    case  6:
      u8g.drawStr(62, 12, "  1");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq);
      break;
    case  7:
      u8g.drawStr(62, 12, "  2");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq / 2);
      break;
    case  8:
      u8g.drawStr(62, 12, "  5");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq / 5);
      break;
    case  9:
      u8g.drawStr(62, 12, " 10");
      u8g.setPrintPos( 62, 48);
      u8g.print(Freq / 10);
      break;
    default: break;
  }
}

//键盘扫描
void Key_scan()
{
  if (digitalRead(Key_add) == LOW)
  {
    while (digitalRead(Key_add) == LOW);
    Key++;
    if (Key == 10)
      Key = 9;
    delay(10);
  }
  if (digitalRead(Key_sub) == LOW)
  {
    while (digitalRead(Key_sub) == LOW);
    Key--;
    if (Key == 0)
      Key = 1;
    delay(10);
  }
  if (digitalRead(Key_hold) == LOW)
  {
    while (digitalRead(Key_hold) == LOW);
    hold = ~hold;
    delay(10);
  }
}

Hi,

Can you explain what your code is supposed to do?

Tom.... :slight_smile:

Its oscilloscope. That uses display from nokia 3310 (84x48).

Edit :

There how it working :

Now its like :

region `text' overflowed by 1156 bytes

Can someone help. Maybe some tricks for my code ?

Unfortunately, the vast majority of the code is not yours.
It is u8glib and some of the other code it pulls in as well.
Any reason why you can't jump to a 168 or 328? They all have very similar costs particularly in low quantities.

One thing you could do is avoid using floating point and instead do integer math and then calculate the integer and mantissa/fractional components separately and then print them as integers separately vs printing a floating point number.
This will keep the floating point Print class code and floating point support routines from being linked in.
That right there should save over 1k of code and would probably get you there.

When debugging at this level you need to be able to see what is being linked in. And order to do that you will need to have a good grasp of embedded tools and how to get a link map and symbol table.
Unfortunately the Arduino IDE is too crippled to be able to generate this "as is". If you are using a real OS like linux you can patch your Arduino IDE platform.txt file to use a wrapper script in place of the avr tool objcopy to allow creating the link map and symbol table each time the code is built.
On Windows, it can be done but is more difficult as windows was not designed to do s/w development and hence does not include native scripting tools.

I have attached sample output files from a build of your code so you can get an idea of what all is being linked in.

--- bill

ugblibTest.zip (49.7 KB)

Thanks you. I have read many threads but only you offer to "split" float numbers into integer. I never really thought about it :o I think it may be solution.

But i have one more question. For example in draw() function, I have this :

u8g.drawStr(62, 6, "MS");

Its static text. But it always "redraws" in loop() function.

Can I something like paste this code from loop() to setup() ?
I mean can I draw it only at the start. And then redraw only "oscilloscope line".

Or its "feature" of display that I need redraw all. And If its possible, will it reduce code size ?

u8g.drawStr(62, 6, "MS");

It doesn't really matter where you call it, the function call is going to take up flash memory, and the "MS" is going to take up precious RAM.

Hi,
What controller is it written for?
Why do you want to use atmega8?

Tom.... :slight_smile: