Arduino Uno, varför kompilerar inte det här???

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Arduino Uno, varför kompilerar inte det här???

Inlägg av mri »

Hej, alla kloka Arduino experter.
Nu har jag för första gången försökt mig på Arduino, men jag kom inte speciellt långt...
Använder Arduino IDE 1.6.4 på min trogna Windows XP maskin.

Följande kod kompilerar inte. Kompileringen avbryts med att ld.exe till synes crashar och avslutas av Windows. I IDE'n står det:

collect2.exe: error: ld returned 5 exit status
Error compiling

Att kompilera för Arduino Uno går inte, men ändrar jag till Arduino Mega går kompileringen igenom.
Det verkar ha nåt med kodstorleken att göra. Kommenterar jag t.ex. bort lcd.begin(16, 2); i setup() eller någon av casen i update_state_machine() så kompilerar den för Uno också. Vad är det jag missat....? Jag använder ju bara en liten del av tillgängligt RAM och ROM.

Koden i sin helhet är:

Kod: Markera allt

#include <LiquidCrystal.h>

#define BEEPER_PORT  13
#define STOP_COUNDNTDOWN_WIRE_PORT  A1
#define DESTRUCT_WIRE_1_PORT  A2
#define DESTRUCT_WIRE_2_PORT  A3
#define DESTRUCT_WIRE_3_PORT  A4
#define CASE_OPEN_SENSOR_PORT  A5

enum States
{
  ARM_CASE,  
  CASE_CLOSED_TIMEOUT,
  CASE_CLOSED,
  CASE_OPENED_DEBOUNCE,
  CASE_OPENED_COUNTDOWN,
  COUNTDOWN_STOPPED,
  DESTRUCT_COUNTDOWN,
  DESTRUCT_NOW,
};

enum States state;
unsigned long state_timeout_start;
unsigned long state_timeout_time;

// The 2x16 LCD shield
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


// Check if case is open
bool isCaseOpen()
{
  return digitalRead(CASE_OPEN_SENSOR_PORT) == HIGH;
}

// Check if stop countdown wire has been cut
bool isStopCoundownWireCut()
{
  return digitalRead(STOP_COUNDNTDOWN_WIRE_PORT) == HIGH;
}

// Check if any of the destruct wires has been cut
bool isDestructWireCut()
{
  return (digitalRead(DESTRUCT_WIRE_1_PORT) == HIGH) ||
         (digitalRead(DESTRUCT_WIRE_2_PORT) == HIGH) ||
         (digitalRead(DESTRUCT_WIRE_3_PORT) == HIGH);
}

unsigned long beep_time;
unsigned long beep_period_time_ms, beep_on_time_ms;

void setBeepRate(unsigned long period_time_ms, unsigned long on_time_ms)
{
  beep_period_time_ms = period_time_ms;
  beep_on_time_ms = on_time_ms;
}

void update_beep()
{
  unsigned long elapsed = millis() - beep_time;

  if (elapsed < beep_on_time_ms)
  {
    digitalWrite(BEEPER_PORT, HIGH);
  }
  else
  {
    digitalWrite(BEEPER_PORT, LOW);
  }
  if (elapsed > beep_period_time_ms)
  {
    beep_time += beep_period_time_ms;
  }
}

void setup() 
{
  // Configure "cut wire" ports as digital inputs with pullup
  pinMode(STOP_COUNDNTDOWN_WIRE_PORT, INPUT_PULLUP);
  pinMode(DESTRUCT_WIRE_1_PORT, INPUT_PULLUP);
  pinMode(DESTRUCT_WIRE_2_PORT, INPUT_PULLUP);
  pinMode(DESTRUCT_WIRE_3_PORT, INPUT_PULLUP);

  // Configure "case open" sensor port as digital input with pullup
  pinMode(CASE_OPEN_SENSOR_PORT, INPUT_PULLUP);

  pinMode(BEEPER_PORT, OUTPUT);
  digitalWrite(BEEPER_PORT, LOW);
 
  // Configure LCD, 16 columns, 2 rows
  lcd.begin(16, 2);
  
  beep_time = millis();
  setBeepRate(1000, 0);
  
  state = ARM_CASE;
  
  Serial.begin(19200);
  Serial.print("Start\n");
}




void loop() 
{
  update_state_machine();
  
  
}

void update_state_machine()
{
  switch (state)
  {  
    default:
    case ARM_CASE:
      if (!isCaseOpen())
      {
        state_timeout_start = millis();
        state_timeout_time = 10*1000;  // Wait in next state for 10 seconds
        state = CASE_CLOSED_TIMEOUT;
        setBeepRate(1000, 1000);    // Constant beep
        Serial.print("state = CASE_CLOSED_TIMEOUT\n");
      }
      break;
      
    case CASE_CLOSED_TIMEOUT:
#if 1
      if (isCaseOpen())
      {
        // Case was opened, go back to previous state
        state = ARM_CASE;
        setBeepRate(1000, 0);  // Silent
        Serial.print("state = ARM_CASE\n");
        break;
      }
      if ((millis() - state_timeout_start) > state_timeout_time)
      {
        setBeepRate(5*1000, 100);  // Short bip every 5 second
        state = CASE_CLOSED;
        Serial.print("state = CASE_CLOSED\n");
      }
#endif      
      break;
      
    case CASE_CLOSED:
#if 0
      if (isCaseOpen())
      {
        state = CASE_OPENED_DEBOUNCE;
        state_timeout_start = millis();
        state_timeout_time = 2*1000;  // Debounce state for 2 second
        Serial.print("state = CASE_OPENED_DEBOUNCE\n");
      }
#endif      
      break;

    case CASE_OPENED_DEBOUNCE:
#if 0
      if (!isCaseOpen())
      {
        // Case was closed, go back to previous state
        state = CASE_CLOSED;
        Serial.print("state = CASE_CLOSED\n");
        break;
      }
      if ((millis() - state_timeout_start) > state_timeout_time)
      {
        state = CASE_OPENED_COUNTDOWN;
        setBeepRate(1000, 100);  // Short bip every second
        Serial.print("state = CASE_OPENED_COUNTDOWN\n");
        break;
      }
#endif      
      break;    

    case CASE_OPENED_COUNTDOWN:
#if 1
      if (isStopCoundownWireCut())
      {
        state = COUNTDOWN_STOPPED;
        setBeepRate(1000, 0);  // Silent
        Serial.print("state = COUNTDOWN_STOPPED\n");
        break;
      }
      if (isDestructWireCut())
      {
        state = DESTRUCT_COUNTDOWN;
        setBeepRate(300, 100);  // Fast short bips
        Serial.print("state = DESTRUCT_COUNTDOWN\n");
        break;
      }
#endif      
      break;    

    case COUNTDOWN_STOPPED:
      break;

    case DESTRUCT_COUNTDOWN:
      break;    
      
    case DESTRUCT_NOW:
      break;
  }

}
Borre
Inlägg: 4574
Blev medlem: 14 juni 2007, 15:43:50
Ort: Hälsingland

Re: Arduino Uno, varför kompilerar inte det här???

Inlägg av Borre »

En snabb googling verkar tyda på att problemet kommer med Arduino på XP. Vissa har tydligen löst det med att kopiera LD.exe från en tidigare version, 1.0.6, så du kan ju prova det.

Din kod kompilerar utan fel för mig, även med Arduino i virtuell Windows XP.
SeniorLemuren
Inlägg: 7859
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Arduino Uno, varför kompilerar inte det här???

Inlägg av SeniorLemuren »

Jag laddade ner AltSoftSerial Library och länkade in. Det gick då att kompilera utan fel.

Kod: Markera allt

#include <AltSoftSerial.h>
#include <LiquidCrystal.h>
...
..
Global variables use 542 bytes (26%) of dynamic memory, leaving 1,506 bytes for local variables. Maximum is 2,048 bytes.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Arduino Uno, varför kompilerar inte det här???

Inlägg av mri »

Googlar man det Borre hänvisar till verkar det vara lite random var som får diverse program att gå igenom kompileringen. För en del räcker det med att deklarera några extra oanvända variabler.

Hursomhelst, jag kopierade in ld.exe from Arduino 1.0.6 och nu fungerar det!
Tack!
Skriv svar