unsigned short int UbirchSIM800::HTTP_get(const char *url, unsigned long int &length, STREAM &file) {
  unsigned short int status = HTTP_get(url, length);
  PRINT("HTTP STATUS: ");
  DEBUGLN(status);
  PRINT("FILE LENGTH: ");
  DEBUGLN(length);

  if (length == 0) return status;

  char *buffer = (char *) malloc(SIM800_BUFSIZE);
  uint32_t pos = 0;
  do {
    size_t r = HTTP_read(buffer, pos, SIM800_BUFSIZE);
#if !defined(NDEBUG) && defined(DEBUG_PROGRESS)
    if ((pos % 10240) == 0) {
      PRINT(" ");
      DEBUGLN(pos);
    } else if (pos % (1024) == 0) { PRINT("<"); }
#endif
    pos += r;
    file.write(buffer, r);
  } while (pos < length);
  free(buffer);
  PRINTLN("");

  return status;
}
boolean URCQueue<i>::Enqueue(const char *pURCText)
{
	if(FCount >= i)
	{
		DEBUG_P(PSTR("** URC Queue is Full"LB));
		return false;
	}

	DEBUG_P(PSTR("Queuing URC --> "));
	DEBUGLN(pURCText);

	char *item = strdup(pURCText);
	if(item)
	{
		FURCQueue[FCount] = item;

		FCount++;    
		return true;
	}
	else
	{
		DEBUG_P(PSTR("**URC Not enough memory"LB));
		return false;
	}
};
ModemGSM::EStandardAnswer ModemGSM::WaitAnswer(unsigned int pTimeoutMS, boolean pHandleURC)
{
	//DEBUG_P("WaitAnswer --> ");
	for(;;)
	{
		if(Readln(pTimeoutMS, false) == TIMEOUT)
		{
			DEBUG_P(PSTR("** TIMEOUT"LB));
			return saTimeout;
		}
		
		//DEBUGLN(FRXBuff);

		if(strcmp_P(FRXBuff,PSTR("OK")) == 0)
		{
			//DEBUGLN_P("OK");
			return saOk;    
		}
		else if(	(strcmp_P(FRXBuff,PSTR("ERROR")) == 0) ||
					(strncmp_P(FRXBuff,PSTR("+CME ERROR:"), 11) == 0) ||
					(strncmp_P(FRXBuff,PSTR("+CMS ERROR:"), 11) == 0))
		{
			DEBUG_P(PSTR("** "));
			DEBUGLN(FRXBuff);
			return saError;    
		}
		else if(pHandleURC)
			HandleURC();
		else
			return saUnknown;    
	}
}
boolean ModemGSM::RegisterNumberInPB(char *pName, char *pNumber)
{
	DEBUG_P(PSTR("Writing PB entry --> "));

	if(pName)
	{
		DEBUG(pName);
		DEBUG_P(PSTR(" : "));
	}
	DEBUGLN(pNumber);

	if(pName)
	{	
		SendCommand(PSTR("AT+CPBW=,\"%s\",,\"%s\""), pNumber, pName);
	}
	else
		SendCommand(PSTR("AT+CPBW=,\"%s\""), pNumber);

	boolean res = WaitAnswer(5000, true) == saOk;

	//Wait a while. It seems that issuing a command immediately after this the modem hangs
	delay(2000);
	
	return res;
}
void UbirchSIM800::print(uint32_t s) {
#ifdef DEBUG_AT
  PRINT("+++ ");
  DEBUGLN(s);
#endif
  _serial.print(s);
}
boolean URCQueue<i>::Dequeue(char *pURCText, size_t pURCTextSize)
{
	if(FCount == 0)
	{
		DEBUG_P(PSTR("** URC Queue is Empty"LB));
		return false;
	}

	DEBUG_P(PSTR("Dequeuing URC --> "));

	if(pURCText)
	{
		strncpy(pURCText, FURCQueue[0], pURCTextSize - 1);
		pURCText[pURCTextSize - 1] = '\0';
		DEBUGLN(FURCQueue[0]);
	}
	else	
		DEBUG_P(PSTR("Value Discarded"LB));

	Dispose(0);

	FCount--;

	memmove(FURCQueue, FURCQueue+1, sizeof(char *) * FCount);

	return true;      
};
unsigned short int UbirchSIM800::HTTP_post(const char *url, unsigned long int &length, STREAM &file, uint32_t size) {
  expect_AT_OK(F("+HTTPTERM"));
  delay(100);

  if (!expect_AT_OK(F("+HTTPINIT"))) return 1000;
  if (!expect_AT_OK(F("+HTTPPARA=\"CID\",1"))) return 1101;
  if (!expect_AT_OK(F("+HTTPPARA=\"UA\",\"UBIRCH#1\""))) return 1102;
  if (!expect_AT_OK(F("+HTTPPARA=\"REDIR\",1"))) return 1103;
  println_param("AT+HTTPPARA=\"URL\"", url);
  if (!expect_OK()) return 1110;

  print(F("AT+HTTPDATA="));
  print(size);
  print(F(","));
  println((uint32_t) 120000);

  if (!expect(F("DOWNLOAD"))) return 0;

  uint8_t *buffer = (uint8_t *) malloc(SIM800_BUFSIZE);
  uint32_t pos = 0, r = 0;

  do {
    for (r = 0; r < SIM800_BUFSIZE; r++) {
      int c = file.read();
      if (c == -1) break;
      _serial.write((uint8_t) c);
    }

    if (r < SIM800_BUFSIZE) {
#if !defined(NDEBUG) && defined(DEBUG_PROGRESS)
      PRINTLN("EOF");
#endif
      break;
    }
#ifndef NDEBUG
    if ((pos % 10240) == 0) {
      PRINT(" ");
      DEBUGLN(pos);
    } else if (pos % (1024) == 0) { PRINT(">"); }
#endif
    pos += r;
  } while (r == SIM800_BUFSIZE);

  free(buffer);
  PRINTLN("");

  if (!expect_OK(5000)) return 1005;

  if (!expect_AT_OK(F("+HTTPACTION=1"))) return 1004;

  // wait for the action to be completed, give it 5s for each try
  uint16_t status;
  while (!expect_scan(F("+HTTPACTION: 1,%hu,%lu"), &status, &length, 5000));

  return status;
}
bool UbirchSIM800::status() {
  println(F("AT+CIPSTATUS=0"));

  char status[SIM800_BUFSIZE];
  expect_scan(F("+CIPSTATUS: %s"), status);
  DEBUGLN(status);
  if (!expect_OK()) return false;

  return strcmp_P(status, PSTR("CONNECTED")) < 0;
}
size_t UbirchSIM800::HTTP_read(char *buffer, uint32_t start, size_t length) {
  print(F("AT+HTTPREAD="));
  print(start);
  print(F(","));
  println((uint32_t) length);

  unsigned long int available;
  expect_scan(F("+HTTPREAD: %lu"), &available);
#ifdef DEBUG_PACKETS
  PRINT("~~~ PACKET: ");
  DEBUGLN(available);
#endif
  size_t idx = read(buffer, (size_t) available);
  if (!expect_OK()) return 0;
#ifdef DEBUG_PACKETS
  PRINT("~~~ DONE: ");
  DEBUGLN(idx);
#endif
  return idx;
}
boolean ModemGSM::WriteSMS(const char *pDestPhoneNumber, const char *pBody,int *pIndex)
{
	boolean res = false;

	DEBUG_P(PSTR("Writing SMS --> %s : "), pDestPhoneNumber);
	DEBUGLN(pBody);

	if(pIndex)
		*pIndex = 0;
	SendCommand(PSTR("AT+CMGW=\"%s\""), pDestPhoneNumber);

	DiscardPrompt(1500);            //Discard modem prompt

	FSerial->print(pBody);

	delay(500);
	FSerial->print(0x1A,BYTE);      //CTRL+Z End of Message


	for(;;)
	{
		//AT+CMGW can take a long time to answer
		switch(WaitAnswer(20000))
		{
			case saOk:
				return res;    
			case saError:
			case saTimeout:
				return false;    
			case saUnknown:
			{
				int idx;

				if(sscanf_P(FRXBuff, PSTR("+CMGW: %d"), &idx) == 1)
				{             
					DEBUG_P(PSTR("SMS Written at index -> %d"LB), idx);

					res = true;

					if(pIndex)
						*pIndex = idx;
				}
				else
					HandleURC();
			}		
		}
	}
}
boolean ModemGSM::ReadSMSAtIndex(int pIndex, TSMSPtr pSMS)
{
	boolean hasEntry = false;

	DEBUG_P(PSTR("Reading SMS entry at --> %d"LB), pIndex);

	SendCommand(PSTR("AT+CMGR=%d"), pIndex);

	for(;;)
	{
		switch(WaitAnswer(5000))
		{
			case saOk:
				return hasEntry;    
			case saError:
			case saTimeout:
				return false;    
			case saUnknown:
			{
				int idx;

				if(sscanf_P(FRXBuff, PSTR("+CMGR: \"%*[^\"]\",\"%20[^\"]\""), pSMS->phone) == 1)
				{             
					DEBUG_P(PSTR("  SMS Number -> %s"LB), pSMS->phone);

					if(Readln(500, true) != 0)
					{ 
						DEBUG_P(PSTR("  SMS Text -> "));
						DEBUGLN(FRXBuff);

						strncpy(pSMS->body, FRXBuff, sizeof(pSMS->body) - 1); 
						pSMS->body[sizeof(pSMS->body) - 1] = '\0';

						hasEntry = true;
					}
					else
					{
						DEBUG_P(PSTR("** Timeout reading SMS text"LB));  
						return false;    
					}    
				}
				else
					HandleURC();
			}		
		}
	}
}
boolean ModemGSM::GetPBEntryByName(const char *pName, char *pNumber, int *pIndex)
{
	boolean hasEntry = false;

	DEBUG_P(PSTR("Reading PB entry --> %s"LB), pName);

	SendCommand(PSTR("AT+CPBF=\"%s\""), pName);

	for(;;)
	{
		switch(WaitAnswer(10000))
		{
			case saOk:
				return hasEntry;    
			case saError:
			case saTimeout:
				return false;    
			case saUnknown:
			{
				int idx;

				//Stop on first entry. 
				if(!hasEntry && (sscanf_P(FRXBuff,PSTR("+CPBF: %d,\"%20[^\"]\""), &idx, pNumber) == 2))
				{
					DEBUGLN(pNumber);
					hasEntry = true;

					if(pIndex)
						*pIndex = idx; 
				}
				else
					HandleURC();
			}
		}
	}
}
Exemple #13
0
bool UbirchSIM800::is_urc(const char *line, size_t len) {
  urc_status = 0xff;

  for (uint8_t i = 0; i < 17; i++) {
#ifdef __AVR__
    const char *urc = (const char *) pgm_read_word(&(_urc_messages[i]));
#else
    const char *urc = _urc_messages[i];
#endif
    size_t urc_len = strlen(urc);
    if (len >= urc_len && !strncmp(urc, line, urc_len)) {
#ifdef DEBUG_URC
      PRINT("!!! SIM800 URC(");
      DEBUG(i);
      PRINT(") ");
      DEBUGLN(urc);
#endif
      urc_status = i;
      return true;
    }
  }

  return false;
}
int ModemGSM::Dispatch()
{
	int res = 0;
	int level;
	int ind;
	static int state=0;

	EvalNetworkLedStatus();

#ifdef REGISTRATION_DELAYED
	if(FNetworkRegDelayActive && FNetworkRegDelayTS.IsExpired())
	{
		DEBUG_P(PSTR("Network Registration Delay Expired --> Now Registered To Network"LB));                    

		FNetworkRegDelayActive = false;
		FRegisteredToNetwork = true;
	}
#endif
	if(FLastKeepAliveTS.IsExpired())
	{
#if SIMULATION
		if(FPBReady)
		{
			int idx;
			char temp[30];

//			switch(state % 3) //repeat commands
			switch(state)
			{
				case 0:
				{
					DEBUG_P(PSTR("---- Posting Fake SMS"LB));
					WriteSMS("+390000000000", "ON 0000,22", &idx);
					sprintf_P(temp, PSTR("+CMTI: \"SM\",%d"), idx);
					break;
				}
				case 1:
				{
					DEBUG_P(PSTR("---- Posting Fake SMS"LB));
					WriteSMS("+390000000000", "ON 0000,22", &idx);
					sprintf_P(temp, PSTR("+CMTI: \"SM\",%d"), idx);
					break;
				}

				default:
				{
					temp[0] = 0;

					if(!SendKeepAlive())
					{
						FKeepAliveFailedCount++;
						//if the modem is not answering try the hard way ...
						if(FKeepAliveFailedCount > 5)
						{
							//Try to power off the modem
							SendCommand("AT+CPWROFF");
							delay(1000);

							//Signal Error condition
							FError = true;
							return res;
						}
					}
					else
					{
						FError = false;
						FKeepAliveFailedCount = 0;
					}				
				}
			}

			state++;
			if(temp[0])
			{
				FURCQueue.Enqueue(temp);			
				DEBUG_P(PSTR("---- Posted Fake SMS"LB));
			}
		}
		else
#endif
			if(!SendKeepAlive())
			{
				FKeepAliveFailedCount++;
				//if the modem is not answering try the hard way ...
				if(FKeepAliveFailedCount > 5)
				{
					//Try to power off the modem
					SendCommand("AT+CPWROFF");
					delay(1000);

					//Signal Error condition
					FError = true;
					return res;
				}
			}
			else
			{
				FError = false;
				FKeepAliveFailedCount = 0;
			}

		FLastKeepAliveTS.Reset();
	};
	
	int idx;
	//Check for Queued URC or Data from Modem SerialLine
	if((FURCQueue.Count() ? FURCQueue.Dequeue(FRXBuff, sizeof(FRXBuff)) : false) || (Readln(100, false) != TIMEOUT))
	{
		if(sscanf_P(FRXBuff, PSTR("+CMTI: \"%*[^\"]\",%d"), &idx) == 1)
		{                
			DEBUG_P(PSTR("SMS Received at -> %d"LB), idx);

			//Save SMS position in SM Memory, the SMS is stored by the Modem
			FSMSInQueue.Enqueue(idx);
		}
		else if((sscanf_P(FRXBuff,PSTR("+CMGS: %d"), &level) == 1) || (sscanf_P(FRXBuff,PSTR("+CMSS: %d"), &level) == 1))
		{
			DEBUG_P(PSTR("Last Message Sent Successfully"LB));
		}
		else if(sscanf_P(FRXBuff,PSTR("+CIEV: %d,%d"), &ind, &level) == 2)
		{
			if(ind == 2)
			{
				if((level >= 1) && (level <= 5))
				{
					FSignalLevel = level;
					DEBUG_P(PSTR("Signal Strength --> %d"LB), level);                    
				}
				else
				{
					FSignalLevel = UNKNOWN_LEVEL;
					DEBUG_P(PSTR("**BAD Signal Strength --> %d"LB), level);                    
				}
			}
		}
		else if(sscanf_P(FRXBuff,PSTR("+CREG: %d"), &level) == 1)
		{
			if((level == 1) || (level == 5))
			{
#ifdef REGISTRATION_DELAYED
				DEBUG_P(PSTR("Registered to Network Indication --> Starting Delay"LB));                    
				FNetworkRegDelayActive = true;
				//Wait for a while to be sure that SMS will work
				FNetworkRegDelayTS.Reset(); 
#else
				FRegisteredToNetwork = true;
				DEBUGLN_P(PSTR("Registered to Network"LB)); 
#endif
			}
			else
			{
				DEBUG_P(PSTR("NOT Registered to Network"LB));
				FRegisteredToNetwork = false;
#ifdef REGISTRATION_DELAYED
				FNetworkRegDelayActive = false;
#endif
			}
			FLastBlinkTS.Reset();
			EvalNetworkLedStatus();
		}
		else if(strncmp(FRXBuff,"+XDRVI: ", 8) == 0)
		{        
			resetCount++;
			DEBUG_P(PSTR("Module RESET"LB));
			DiscardSerialInput(5000);
			InnerSetup();
		}
		else if(strcmp_P(FRXBuff,PSTR("+PBREADY")) == 0)
		{        
			FPBReady = true;
			for(int i = 0; i < 10; i++)
				if(ClearSMSMemory())
					break;
				else
				{
					delay(1000);
					DEBUG_P(PSTR("Retrying .... "LB));
				}
				
			FLastKeepAliveTS.Reset();
		}
		else
		{
			DEBUG_P(PSTR("** Unhandled -> "));
			DEBUGLN(FRXBuff);
		}    
	}

	//Do not fire SMS retries if the network is not available
	if((FSMSOutQueue.Count() && FRegisteredToNetwork) && !(FSMSResendPending && !FSMSResendTS.IsExpired()))    
	{
		int idx;

		FSMSOutQueue.Peek(&idx);
		
		if(SendSMSAtIndex(idx))
		{
			SMSDequeue(qOut, NULL);
			FSMSResendPending = false;
		}
		else
		{
			//A retry failed ?
			if(FSMSResendPending)
			{
				//some other retry available ?
				if(FSMSRetry)
				{
					FSMSRetry--;
					FSMSResendTS.Reset();
					DEBUG_P(PSTR("Retrying SMS Send. Retry Count --> %d"LB), (int)FSMSRetry);
				}
				else
				{
					//discard SMS
					FSMSResendPending = false;
					FSMSOutQueue.Dequeue(NULL);
					DEBUG_P(PSTR("** Too Many Retries SMS Send Aborted"LB));
				}
			}
			else
			{
				//Start a delay and retry sequence
				FSMSRetry = SMS_RETRY_COUNT;
				FSMSResendPending = true;
				FSMSResendTS.Reset();
				DEBUG_P(PSTR("Retrying SMS Send. Retry Count --> %d"LB), (int)FSMSRetry);
			}		
		}
	}

	return res;
}
Exemple #15
0
/*EDU US*/ 	void rgb_lcd::effectiveNewWrite(String newString){
	//--- On crée des variables locales 
		int8_t userCol;			// Utilisée pour sauvegarder la position du curseur utilisateur
	
	//--- On sauvegarde la position du curseur de l'utilisateur
		userCol = m_curentCol;

	//--- On récupère la ligne courante
		DEBUG2("La ligne courante est : ", m_curentRow); 
				
	//--- On récupère la colonne courante
		DEBUG2("La colonne courante est : ", m_curentCol);
	
	//--- On récupère la dernière taille max à partir de temp
		int8_t maxLength=m_maxLength[m_curentCol][m_curentRow];
		DEBUG2("La derniere taille max enregistree est : ", maxLength);
	
	//--- Détermination de la taille du nbr reçu
		int8_t  newMaxLength=newString.length();
		DEBUG2("La nouvelle taille max est : ", newMaxLength);
			
	//--- On compare et enregistre la taille max
		int8_t curentLength;
		if(newMaxLength>maxLength){
		// Il faut sauvegarder la nouvelle valeurs
			m_maxLength[m_curentCol][m_curentRow]=newMaxLength;
		// Sauvegarde dans une variable pratique 
			curentLength=newMaxLength;
			DEBUG2("On enregistre la nouvelle taille max avec : ", m_maxLength[m_curentCol][m_curentRow]);
		} 
		else {
		// Sauvegarde dans une variable pratique 
			curentLength=maxLength;
			DEBUG2("On garde l ancienne valeur de taille max : ", m_maxLength[m_curentCol][m_curentRow]);
		}
			
	//--- TEMP: On construit une chaine à partir de la ligne courante et de la position du curseur
		//-- On construit 1 chaîne vide
		char tempRow[16];
		//-- On remplit la chaine avec des valeurs par défaut
		for(int8_t k=0;k<NBR_COLS;k++){
			tempRow[k]='-';	
		}
			
	//--- TEMP: On ajoute le nombre reçu à la ligne courante et à l'endroit du curseur 
		//-- On complète la chaîne newString pour qu'elle ait la longueur max constatée
		//-- La taille de la chaîne doit être de curentLength
		//-- On compare la longeur réelle et la longeur souhaitée
		int8_t diffLength = maxLength-newMaxLength;
		DEBUG2("La difference de longeur (pour cette position) est de :", diffLength);
		
		//-- On teste si le nombre à diminué de longueur
		if(diffLength>0){
			//- Il faut alors complèter la chaîne car elle est trop courte
			for(int8_t i=0;i<=diffLength;i++){
				//- On ajoute un x à la chaîne
				newString+=' ';
			}
			DEBUG2("Des 0 ont été ajoutés. La chaîne vaut maitenant : ", newString);
		}
			
	//--- On enregistre la nouvelle chaîne temp. On commence la boucle à l'endroit du curseur
		for(int8_t  i=0;i<curentLength;i++){
			//-Ecriture du nouveau mot dans la ligne courente du tableau temp
			tempRow[m_curentCol+i]=newString[i];
		}
				
		//-- Affichage de la ligne TEMP => Serial
		DEBUG_TAB("La chaine temp vaut maintenant : ",tempRow,0,16);
		//for(int8_t i=0;i<16;i++){Serial.print(tempRow[i]);} Serial.println(" "); 
		
		//--- Affichage de memory => Serial
		DEBUG_TAB2("MEMORY (avant modifications) contient : ", m_memory,0,15,0,1);
		//for(int8_t i=0;i<16;i++){Serial.print(m_memory[i][0]);} Serial.println(" "); 
		//for(int8_t i=0;i<16;i++){Serial.print(m_memory[i][1]);} Serial.println(" ");	
		
	
	//--- On va comparer la ligne temp avec m_memory uniquement sur la plage taille max
		DEBUG("Debut comparaison entre la ligne temp et m_memory - ");
		DEBUGLN("La comparaison se fait case par case sur la ligne courante");
		
		// INFOS : Debut de la boucle=position curseur (m_curentCol)
		// INFOS : Fin de la boucle = position curseur+largeur max

		//-- On calcule le début de la boucle
		int8_t startTest = m_curentCol;
			
		//-- On calcule la fin de la boucle
		int8_t endTest = startTest+curentLength;
		
		//-- Rappel colone utilisateur
		DEBUG2("Colonne utilisateur : ", userCol);
		
		//-- On lance la comparaison sur la plage active
		for(int8_t c=startTest;c<endTest;c++){
		
			//-- Comparaison case par case
			if(tempRow[c]!=m_memory[c][m_curentRow]){
				DEBUG2("Case : ", c);
				//Serial.print("Case : "); Serial.print(c); 
				DEBUG2(" : ", tempRow[c]);
				//Serial.print(" : "); Serial.print(tempRow[c]); 
				DEBUG2(" different de : ", m_memory[c][m_curentRow]);
				//Serial.print(" different de : "); Serial.print(m_memory[c][m_curentRow]); 
				DEBUG(" => Requete I2C necessaire ! ");
				//Serial.print(" => Requete I2C necessaire ! "); 
								
				//-- On enregistre la nouvelle valeur dans m_memory
				m_memory[c][m_curentRow]=tempRow[c];
				//-- On se rappelle qu'écire déplace le curseur
				//-- On envoit une reqête I2C

				//-On place le curseur à l'endroit de la modification
				setCursorOn(m_curentRow,c);
				DEBUG2("Curseur place en : ",c);
				
				// >>> EFECTIVE WRITE !
				DEBUG2("Ecriture I2C de : ", tempRow[c]);
				write(tempRow[c]);
					
			}
			else{
				
				DEBUG2("Case : ", c);
				DEBUG2(" : ", tempRow[c]);	
				DEBUG2(" egale a : ", m_memory[m_curentRow][c]);				
				
			}
		}
			
			//-- On replace le curseur après la fin du mot courant
				//- On calcule la nouvelle position souhaitée pour le curseur
				int8_t newPos;
				newPos = userCol + curentLength;
				setCursorOn(m_curentRow, newPos);   // setCursor change automatiquement la position courante
				
	//--- Affichage de memory => Serial
		DEBUG_TAB2("MEMORY (apres modifications) contient : ", m_memory,0,15,0,1);
				
}
Exemple #16
0
//
// Copied largely unchanged from Marlin
//
void Device_Heater::DoPidAutotune(uint8_t device_number, float temp, int ncycles)
{
  float input = 0.0;
  int cycles = 0;
  bool heating = true;

  unsigned long temp_millis = millis();
  unsigned long t1=temp_millis;
  unsigned long t2=temp_millis;
  long t_high = 0;
  long t_low = 0;

  long bias, d;
  float Ku, Tu;
  float Kp, Ki, Kd;
  float max = 0;
  float min = 10000;
  uint8_t p;
  uint8_t i;

  extern volatile bool temp_meas_ready;
  
  DEBUGLNPGM("PID Autotune start");
  
  // switch off all heaters during auto-tune
  for (i=0; i<Device_Heater::GetNumDevices(); i++)
  {
    if (Device_Heater::IsInUse(i))
      Device_Heater::SetHeaterPower(&heater_info_array[device_number], 0);
  }

  HeaterInfo *heater_info = &heater_info_array[device_number];
  
  bias = d = p = heater_info->power_on_level;
  SetHeaterPower(heater_info, p);

  for(;;) 
  {
    if(temp_meas_ready == true) 
    { // temp sample ready
      Device_TemperatureSensor::UpdateTemperatureSensors();

      input = Device_Heater::ReadCurrentTemperature(device_number);

      max=max(max,input);
      min=min(min,input);
      if(heating == true && input > temp) 
      {
        if(millis() - t2 > 5000) 
        { 
          heating=false;
          p = bias - d;
          SetHeaterPower(heater_info, p);
          t1=millis();
          t_high=t1 - t2;
          max=temp;
        }
      }
      if(heating == false && input < temp) 
      {
        if(millis() - t1 > 5000) {
          heating=true;
          t2=millis();
          t_low=t2 - t1;
          if(cycles > 0) {
            bias += (d*(t_high - t_low))/(t_low + t_high);
            bias = constrain(bias, 20 ,heater_info->power_on_level-20);
            if (bias > heater_info->power_on_level/2) 
              d = heater_info->power_on_level - 1 - bias;
            else 
              d = bias;

            DEBUGPGM(" bias: "); DEBUG_F(bias, DEC);
            DEBUGPGM(" d: "); DEBUG_F(d, DEC);
            DEBUGPGM(" min: "); DEBUG(min);
            DEBUGPGM(" max: "); DEBUGLN(max);
            
            if(cycles > 2) 
            {
              Ku = (4.0*d)/(3.14159*(max-min)/2.0);
              Tu = ((float)(t_low + t_high)/1000.0);
              DEBUGPGM(" Ku: "); DEBUG(Ku);
              DEBUGPGM(" Tu: "); DEBUGLN(Tu);
              Kp = 0.6*Ku;
              Ki = 2*Kp/Tu;
              Kd = Kp*Tu/8;
              DEBUGLNPGM(" Clasic PID ");
              DEBUGPGM(" Kp: "); DEBUGLN(Kp);
              DEBUGPGM(" Ki: "); DEBUGLN(Ki);
              DEBUGPGM(" Kd: "); DEBUGLN(Kd);
              /*
              Kp = 0.33*Ku;
              Ki = Kp/Tu;
              Kd = Kp*Tu/3;
              DEBUGLNPGM(" Some overshoot ")
              DEBUGPGM(" Kp: "); DEBUGLN(Kp);
              DEBUGPGM(" Ki: "); DEBUGLN(Ki);
              DEBUGPGM(" Kd: "); DEBUGLN(Kd);
              Kp = 0.2*Ku;
              Ki = 2*Kp/Tu;
              Kd = Kp*Tu/3;
              DEBUGLNPGM(" No overshoot ")
              DEBUGPGM(" Kp: "); DEBUGLN(Kp);
              DEBUGPGM(" Ki: "); DEBUGLN(Ki);
              DEBUGPGM(" Kd: "); DEBUGLN(Kd);
              */
            }
          }
          p = bias + d;
          SetHeaterPower(heater_info, p);
          cycles++;
          min=temp;
        }
      } 
    }
    if(input > (temp + 20)) 
    {
      ERRORLNPGM("PID Autotune failed! Temperature too high");
      return;
    }
    if(millis() - temp_millis > 2000) 
    {
      DEBUGLNPGM("ok T:");
      DEBUG(input);   
      DEBUGPGM(" @:");
      DEBUGLN(p);       
      temp_millis = millis();
    }
    if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) 
    {
      ERRORLNPGM("PID Autotune failed! timeout");
      return;
    }
    if(cycles > ncycles) 
    {
      DEBUGLNPGM("PID Autotune finished! Record the last Kp, Ki and Kd constants");
      return;
    }
  }
}
Exemple #17
0
Fichier : vm.c Projet : erik/atto
TValue vm_interpret(AttoVM* vm, AttoBlock* block, int start, int argc)
{
    DEBUGF("Interpret block: %d ops\n", block->code->size);
    int error            = 0;
    TValue* max          = (TValue*)(block->code->elements + start + block->code->size);
    TValue *pc_val       = (TValue*)(block->code->elements + start);
    Instruction i        = TV2INST(*pc_val);
    Stack *stack         = &block->stack;
    const char* opcode_names[] = { OPCODE_NAMES };
    const char* op_name = NULL;

    int x;
    for(x = 0; pc_val < max && !error; ++x) {

        op_name = i >= NUM_OPS ? "unknown" : opcode_names[i];

        if(i >= NUM_OPS) {
            ERROR("bad opcode: %d", i);
        }

        DEBUGF("[%d]\t%s (%d)\n", x, op_name, i);
        switch(i) {
        case OP_NOP:
            DISPATCH;
        case OP_POP:
            EXPECT_ON_STACK(1);
            TValue v = pop(stack);
            valueDestroy(&v);
            DISPATCH;
        case OP_DUP: {
            EXPECT_ON_STACK(1);
            TValue v = pop(stack);
            push(stack, v);
            push(stack, v);
            DISPATCH;
        }
        case OP_SWAP: {
            EXPECT_ON_STACK(2);
            TValue f = pop(stack);
            TValue s = pop(stack);
            push(stack, f);
            push(stack, s);
            DISPATCH;
        }
        case OP_ADD:
        case OP_SUB:
        case OP_MUL:
        case OP_DIV:
        case OP_MOD:
        case OP_POW: {
            EXPECT_ON_STACK(2);
            TValue b = pop(stack);
            TValue a = pop(stack);
            TValue res = MathOp(i, a, b);

            push(stack, res);

            DISPATCH;
        }
        case OP_OR:
        case OP_AND:
        case OP_XOR: {
            EXPECT_ON_STACK(2);
            TValue b = pop(stack);
            TValue a = pop(stack);
            TValue res = BitwiseOp(i, a, b);

            push(stack, res);

            DISPATCH;
        }
        case OP_NOT: {
            EXPECT_ON_STACK(1);
            TValue a = pop(stack);
            push(stack, createNumber(~(long)TV2NUM(a)));
            DISPATCH;
        }
        case OP_EQ:
        case OP_LT:
        case OP_GT:
        case OP_LTE:
        case OP_GTE:
        case OP_CMP: {
            EXPECT_ON_STACK(2);
            TValue b = pop(stack);
            TValue a = pop(stack);
            TValue res = ComparisonOp(i, a, b);

            push(stack, res);

            DISPATCH;
        }
        case OP_IF: {
            EXPECT_ON_STACK(1);
            TValue t = pop(stack);
            if(boolValue(t)) {
                NEXTINST;
            }
            DISPATCH;
        }
        case OP_JMP: {
            EXPECT_ON_STACK(1);
            long jmp = (long)TV2NUM(pop(stack));
            if(jmp + pc_val >= max || jmp + (long)pc_val < 0) {
                ERROR("Invalid jump: %ld", jmp);
            }
            pc_val += jmp;
            DISPATCH;
        }
        case OP_PUSHCONST: {
            int index = TV2INST(*++pc_val);
            if(index >= (int)block->k->size) {
                ERROR("Constant index out of bounds: %d", index);
            }
            TValue k = getIndex(block->k, index);

            push(stack, k);
            DISPATCH;
        }
        case OP_PUSHVAR: {
            int index = TV2INST(*++pc_val);

            if(index < 0 || index >= block->sizev) {
                ERROR("Variable index out of bounds: %d", index);
            }

            DEBUGF("PUSHVAR, index %d, value >> %s\n", index, TValue_to_string(block->vars[index]));

            TValue var = block->vars[index];
            var.value.var.index = index;

            block->vars[index] = var;

            push(stack, var);
            DISPATCH;
        }
        case OP_SETVAR: {
            EXPECT_ON_STACK(2);
            TValue var = pop(stack);

            if(var.type != TYPE_VAR) {
                ERROR("Expected a var, but got %s", TValue_type_to_string(var));
            }

            int index = var.value.var.index;

            TValue *val = malloc(sizeof(TValue));

            *val = pop(stack);

            block->vars[index] = createVar(val);

            DEBUGF("SETVAR, index %d, value >> %s\n", index, TValue_to_string(block->vars[index]));

            DISPATCH;
        }
        case OP_VALUEVAR: {
            EXPECT_ON_STACK(1);
            TValue var = pop(stack);

            if(var.type != TYPE_VAR) {
                ERROR("Expected a var, but got %s", TValue_type_to_string(var));
            }

            Value val = *var.value.var.value;
            AttoType type = var.value.var.type;

            TValue t;
            t.value = val;
            t.type = type;

            push(stack, t);
            DISPATCH;
        }
        case OP_BOOLVALUE: {
            EXPECT_ON_STACK(1);

            TValue tos = pop(stack);

            int bool = boolValue(tos);

            valueDestroy(&tos);

            push(stack, createBool(bool));
            DISPATCH;
        }
        case OP_CONCAT: {
            EXPECT_ON_STACK(2);
            TValue top = pop(stack);
            TValue sec = pop(stack);

            if(!(top.type == TYPE_STRING && sec.type == TYPE_STRING)) {
                ERROR("Expected two string values, but got %s and %s", TValue_type_to_string(sec),
                      TValue_type_to_string(top));
            }

            char *top_s = TV2STR(top);
            char *sec_s = TV2STR(sec);


            char *str = malloc(strlen(top_s) + strlen(sec_s));

            strcpy(str, sec_s);
            strcat(str, top_s);

            valueDestroy(&top);
            valueDestroy(&sec);

            push(stack, createString(str, strlen(str), 0));
            free(str);
            DISPATCH;
        }
        case OP_PRINT: {
            EXPECT_ON_STACK(1);
            TValue v = pop(stack);
            char *str = TValue_to_string(v);

            printf("%s", str);

            if(v.type == TYPE_NUMBER) free(str);
            valueDestroy(&v);
            DISPATCH;
        }
        case OP_READLINE: {
            char *buf = malloc(BUFSIZ);
            memset(buf, '\0', BUFSIZ);
            if(fgets(buf, BUFSIZ, stdin) ) {
                char *nl = strchr(buf, '\n');
                if(nl) {
                    *nl = '\0';
                }
            }

            unsigned len = strlen(buf) + 1;
            push(stack, createString(buf, len, 0));

            free(buf);
            DISPATCH;
        }
        case OP_DUMPSTACK:
            print_stack(*stack);
            DISPATCH;

        case OP_CLEARSTACK: {
            Stack s = StackNew();
            StackDestroy(&block->stack);
            *stack = s;
            DISPATCH;
        }
        case OP_CALL: {
            EXPECT_ON_STACK(2);
            TValue fcn = pop(stack);
            TValue num = pop(stack);

            // FIXME: this explodes when types aren't right :(
            if(fcn.type != TYPE_FUNCTION || num.type != TYPE_NUMBER) {
                ERROR("Expected function and numeric values, but got %s and %s", TValue_type_to_string(fcn),
                      TValue_type_to_string(num));
            }

            int nargs = (int)TV2NUM(num);

            EXPECT_ON_STACK(nargs);

            int j;
            for(j = 0; j < nargs; ++j) {
                TValue v = pop(stack);
                push(&fcn.value.function.b->stack, v);
            }

            TValue ret = vm_interpret(vm, fcn.value.function.b, 0, nargs);

            if(ret.type != TYPE_NULL) {
                push(stack, ret);
            }

            valueDestroy(&fcn);
            valueDestroy(&num);
            valueDestroy(&fcn);

            DISPATCH;
        }
        case OP_RETURN: {
            EXPECT_ON_STACK(1);

            TValue ret = pop(stack);

            DEBUGF("Finished block, returning with %s\n", TValue_to_string(ret));

            return ret;

            DISPATCH;
        }
        default:
            ERROR("Unrecognized opcode: %d", i);
        }
    }

    DEBUGLN("Finished block");
    return createNull();
}