Mehr Ram für einen ATMega328


guten tag zusammen,

ich habe einen code der zwar nicht komplex oder groß ist, aber viel speicherplatz für variablen belegt.

konkret:
programmspeicher: 24.638/30.720bytes (80%)
dynamischer speicher: 1.638/2.048bytes (79%)

die ide sagt mir auch schon, dass es stabilitätsprobleme geben könnte.
wenn der sketch nur kurz läuft, funktioniert es auch ohne probleme, nur wenn er länger läuft und mehrere requests bearbeiten musste (nicht gleichzeitig sondern ca. 30 sec. auseinander) schmiert er einfach ab.
mit "abschmieren" meine ich: er reagiert nicht mehr auf eingehende verbindungen und über die serielle schnittstelle gibt er nur noch diese "fragenzeichenblöcke" aus. einen ascii wert der nicht zwischen 33 und 126 liegt. schätze mal dieser stelle gibt er nur irgendwelchen ram garbage aus.

meine vermutung ist, dass es wirklich dem wenig freien speicherplatz liegt. wenn ich z.b. das komplette struct "ircodes" herausnehme sind wieder 807 bytes für den ram frei und alles läuft stabil.

jetzt ist die frage: wie kann ich den sketch kleiner gestalten, oder gibt es einen ähnlichen chip wie den 328 nur mit mehr ram? einen atmega2560 möchte ich ungern nehmen, da die pins einfach nicht benötigt werden, das projekt auch noch relativ klein gehalten werden soll und ich nicht das werkzeug und kenntnisse für smd bauteile habe.


hier noch der code:
code: [select]
#define wlan_ssid       "ap"
#define wlan_pass       "passwort"
#define wlan_security   wlan_sec_wpa2
#define listen_port           7
#define adafruit_cc3000_irq   2
#define adafruit_cc3000_vbat  5
#define adafruit_cc3000_cs    10
#define ir_rate 92
#define pwm_pin 6

#include <adafruit_cc3000.h>
#include <spi.h>
#include <irremote.h>
#include "utility/debug.h"
#include "utility/socket.h"


adafruit_cc3000 cc3000 = adafruit_cc3000(adafruit_cc3000_cs, adafruit_cc3000_irq,
                         adafruit_cc3000_vbat, spi_clock_divider);


int validatetele();

adafruit_cc3000_server echoserver(listen_port);
irsend irsend;

struct ircodes_struc {
  char name[10];
  long code[5];
};

const ircodes_struc ircodes[13] = {{"rot  ", {0xd720df, 0xf710ef, 0xf730cf, 0xf708f7, 0xf728d7}},
  {"gruen", {0xf7a05f, 0xf7906f, 0xf7b04f, 0xf78877, 0xf7a857}},
  {"blau ", {0xf7609f, 0xf750af, 0xf7708f, 0xf748b7, 0xf76897}},
  {"weiss", {0xf7e01f}},
  {"on", {0xf7c03f}},
  {"off", {0xf740bf}},
  {"dimm_up", {0xf700ff}},
  {"dimm_down", {0xf7807f}},
  {"flash", {0xf7d02f}},
  {"strobe", {0xf7f00f}},
  {"fade", {0xf7c837}},
  {"smooth", {0xf7e817}}
};

typedef struct
{
  char header[2];
  char tart[5];
  char message_type[1];
  char tele_id[6];
  char auftrag_id[6];
  char nutzdaten[20];
} soc_telegramm;

typedef struct
{
  char header[2];
  char teleid[6];
  char tart[5];
  char returncode[2];
} soc_quittung;

soc_telegramm recv_buff;
soc_quittung quittung;

int verbunden = 0;
int old_val = 0;
char ip[15];

void send_ir(long code)
{
  serial.println(f("sende"));
  (int x = 0; x != 3; x++)
  {
    irsend.sendnec(code, ir_rate);
    delay(40);
  }
}

void send_na()
{
  uint32_t ipadress = cc3000.ip2u32(192, 168, 178, 24);
  adafruit_cc3000_client www = cc3000.connecttcp(ipadress, 8888);
  if (www.connected()) {
    serial.println("sende na");
    strncpy(recv_buff.header, "he", 2);
    strncpy(recv_buff.tart, "na   ", 5);
    strncpy(recv_buff.message_type, "n", 1);
    strncpy(recv_buff.tele_id, "000001", 6);
    strncpy(recv_buff.auftrag_id, "      ", 6);
    strncpy(recv_buff.nutzdaten, "ledli", 5);

    www.write((char*)&recv_buff, 25);
  }
  else
  {
    serial.println(f("connection failed"));
    return;
  }

  while (www.available()) {
    char c = www.read();
    serial.print(c);
  }
  www.close();
  memset((char*)&recv_buff, '\0', sizeof(recv_buff));
}

void setup(void)
{
  serial.begin(115200);

  strncpy(quittung.header, "qu", 2);
  serial.println(f("start"));

  if (!cc3000.begin())
  {
    serial.println(f("couldn't begin()! check wiring?"));
    while (1);
  }

  if (!cc3000.connecttoap(wlan_ssid, wlan_pass, wlan_security))
  {
    serial.println(f("failed!"));
    while (1);
  }

  while (!cc3000.checkdhcp())
  {
    delay(100);
  }

  pinmode(pwm_pin, output);

  while (! displayconnectiondetails()) {
    delay(1000);
  }
  serial.println(f("los gehts"));

  echoserver.begin();
  send_na();
  serial.println(f("starte loop"));

}

void loop(void)
{
  adafruit_cc3000_clientref client = echoserver.available();
  if (client)
  {
    serial.println("neuer client");
    if (client.available() > 0)
    {
      uint8_t ch = client.read((char*)&recv_buff, sizeof(recv_buff));
      memcpy(quittung.teleid, recv_buff.tele_id, 6);
      memcpy(quittung.tart, recv_buff.tart, 5);
      if (validatetele() < 0)
        memcpy(quittung.returncode, "01", 2);
      else
        memcpy(quittung.returncode, "00", 2);
      client.write((char*)&quittung, sizeof(quittung));
      verbunden = 1;
    }
    if (verbunden)
    {
      if (strncmp("led  ", recv_buff.tart, 5) == 0)
      {
        /*serial.println("led");
        serial.println("set weissen led stripe zu");
        serial.println(recv_buff.nutzdaten);*/
        int val = atoi(recv_buff.nutzdaten);
        if (val != old_val)
        {
          if (val > old_val)
          {
            while (val != old_val)
            {
              old_val++;
              analogwrite(pwm_pin, old_val);
              delay(10);
            }
            //serial.println(f("fertig"));
          }
          else
          {
            while (val < old_val)
            {
              old_val--;
              analogwrite(pwm_pin, old_val);
              delay(10);
            }
            //serial.println(f("fertig"));
          }
          uint32_t ipadress = cc3000.ip2u32(192, 168, 178, 24);
          adafruit_cc3000_client www = cc3000.connecttcp(ipadress, 8888);
          if (www.connected())
          {
            serial.println(f("sende led"));
            strncpy(recv_buff.header, "he", 2);
            strncpy(recv_buff.tart, "ledst", 5);
            strncpy(recv_buff.message_type, "n", 1);
            strncpy(recv_buff.tele_id, "000001", 6);
            strncpy(recv_buff.auftrag_id, "      ", 6);
            sprintf(recv_buff.nutzdaten, "%d", old_val);
            //strncpy(recv_buff.nutzdaten, (char*), 5);

            www.write((char*)&recv_buff, 23);
          }
          else
          {
            serial.println(f("connection failed"));
            return;
          }

          while (www.available())
          {
            char c = www.read();
            serial.print(c);
          }
          www.close();
          memset((char*)&recv_buff, '\0', sizeof(recv_buff));
        }
        serial.println(f("zurueck in idle"));
      }
      else if (strncmp("rgb  ", recv_buff.tart, 5) == 0)
      {
        (int = 0; != 12; i++)
        {
          if (strcmp(ircodes[i].name, recv_buff.nutzdaten) == 0)
          {
            send_ir(ircodes[i].code[0]);
          }
          else if (strncmp(ircodes[i].name, recv_buff.nutzdaten, 5) == 0)
          {
            int code_index = atoi(&recv_buff.nutzdaten[5]);
            send_ir(ircodes[i].code[code_index]);
          }
        }
      }
      memset(recv_buff.nutzdaten, '\0', sizeof(recv_buff.nutzdaten));
      verbunden = 0;
      serial.println(f("zurueck in idle"));
    }
  }
}

bool displayconnectiondetails(void)
{
  uint32_t ipaddress, netmask, gateway, dhcpserv, dnsserv;

  if (!cc3000.getipaddress(&ipaddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    serial.println(f("unable retrieve ip address!\r\n"));
    return false;
  }
  else
  {
    serial.println((uint8_t)(ipaddress)); */
    serial.println(test1);
    serial.print(f("\nip addr: ")); cc3000.printipdotsrev(ipaddress);
    serial.print(f("\nnetmask: ")); cc3000.printipdotsrev(netmask);
    serial.print(f("\ngateway: ")); cc3000.printipdotsrev(gateway);
    serial.print(f("\ndhcpsrv: ")); cc3000.printipdotsrev(dhcpserv);
    serial.print(f("\ndnsserv: ")); cc3000.printipdotsrev(dnsserv);
    serial.println();
    return true;
  }
}

int validatetele()
{
  //todo: realisieren
  return 0;
}

meine vermutung ist, dass es wirklich dem wenig freien speicherplatz liegt.
wenn ich z.b. das komplette struct "ircodes" herausnehme sind wieder 807 bytes für den ram frei und alles läuft stabil.
du könntest die struktur in den programmspeicher verlagern,
sie scheint mir nur gelesen zu werden, oder?




Arduino Forum > International > Deutsch (Moderator: uwefed) > Mehr Ram für einen ATMega328


arduino

Comments