Show Posts
Pages: [1] 2 3 ... 5
1  Development / Other Software Development / Re: Arduino modbus communication on: June 02, 2011, 03:30:12 pm
There is a MODBUS library available for arduino (in the archive section).  There is serial support but you would need read up on the comments because I believe that there is a short coming with the arduino serial library when used with MODBUS.  You should be able to use an RS232 to RS485 converter from B&B electronics.

If you search online there is software (trial/freeware) to test communication with the RTU as well.

Eric
2  Development / Other Software Development / Re: Agentuino - A lightweight SNMP Agent on: June 02, 2011, 03:24:23 pm
Please take a look at the library's class constructor to see how to use the session struct.  Based on your posted code your missing some parameters.

Code:
// set community name set/get sizes

session->setSize = strlen(session->setCommName);

session->getSize = strlen(session->getCommName);

//

// validate get/set community name sizes

if ( session->setSize > SNMP_MAX_NAME_LEN || session->getSize > SNMP_MAX_NAME_LEN ) {

return SNMP_API_STAT_NAME_TOO_BIG;

}

//

// set session property

_session = session;

//

// validate session port number

if ( session->port == NULL || session->port == 0 ) session->port = SNMP_DEFAULT_PORT;

//

// init UDP socket

_socket.initUDP(session->port);

//

return SNMP_API_STAT_SUCCESS;
3  Development / Other Software Development / Re: DuinOS: Small and Simple OS based on FreeRTOS on: May 17, 2011, 08:40:26 pm
Another tip; you only require a mutex/semaphore if the resource is being shared with more than one tasks.

For example;  if you are using i2c for one device a mutex isn't required per say.
Code:

static void vI2CTask(void *pvParameters) {

   /* The parameters are not used. */
   ( void ) pvParameters;

   portENTER_CRITICAL();
   {
        // init i2c
   }
   portEXIT_CRITICAL();

  /* Cycle for ever, delaying then checking all the other tasks are still
     operating without error. */
   for( ;; ) {
      // read i2c device
      // process data
      // sleep for 10 seconds
   }
}

The "critical" section halts background tasks and allows the code to execute atomically alleviating potential synch issues.  Additional information is available in the FreeRTOS on-line documentation.  If you have done C# threaded programming its similar to a "lock" call.
4  Development / Other Software Development / Re: DuinOS: Small and Simple OS based on FreeRTOS on: May 17, 2011, 04:32:56 pm
You need to modify your stack size within the config file using the default port because there is an initial task created using macros to mimic the arduino structure;  e.g. loop() {}.  Even if you don't have any code in the "loop" function a task is created regardless.

You can make the changes suggested in the initial posting as it alleviates this problem and gives you more control.  Furthermore your using native FreeRTOS calls instead of regenerated wrappers/macros serving the same purpose e.g. createTaskLoopWithStackSize versus native xTaskCreate(vShtReadTask, (signed portCHAR *) "ShtRead", 304, NULL, NORMAL_PRIORITY, &xShtReadHandle).

Eric
5  Development / Other Software Development / Re: DuinOS: Small and Simple OS based on FreeRTOS on: May 10, 2011, 11:15:18 am
rama.stefan the DuinOS files would need to modified to accept the Mega 2560.  There isn't much of a difference between them.

Bima yes, the Ethernet library works "as is" provided no other SPI devices are being used.  The Ethernet library needs to be initialized within the task declaration using the portENTER_CRITICAL() call as shown in my posted example (e.g. vNetSvcTask).  Also, this was tested and is being used on a mega and not the Uno (limited RAM).

Eric
6  Development / Other Software Development / Re: Agentuino - A lightweight SNMP Agent on: March 28, 2011, 11:01:49 am
Take a look at the Agentuino constructors as there is one that allows you to set the community names.  This would allow you to declare public variables within your sketch that could be updated by a web form.  You may want to store them in EEPROM as well or any new settings will be lost on reboot.

You may want to look at a Webduino library; multi web page/form implementation is easier per say.

Eric
7  Development / Other Software Development / Re: Problems with my webserver on: February 27, 2011, 11:37:39 am
Can you paste the html that gets outputted?

Alternatively you may want to take a look at Webduino by Ben Combee and Ran Talbott.
8  Development / Other Software Development / DuinOS: Small and Simple OS based on FreeRTOS on: February 24, 2011, 07:38:10 pm
Continuation of the original thread located here; http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1256745982

Well I've been making some progress with the FreeRTOS port for Arduino.

- Ethernet Library works

Polling three sensors using bitbang, serial interface, and web server on my Mega - Serial and Ethernet are non interrupt mode at the moment.  Pretty impressive what can be packed into an 8-bit MCU.  

A few modifications are needed with the DuinOS files but basically it strips all of the Arduino friendly functions/macros used to call the native FreeRTOS functions.  I am using the native FreeRTOS API functions for simplicity.  It simply doesn't make sense to re-invent the wheel considering documentation already exists.

Here is a code snippet:
Code:
static void vNetSvcTask(void *pvParameters) {
  /* The parameters are not used. */
  ( void ) pvParameters;
  
  /* Initialize the web server library
     with the IP address and port you want to use
     (port 80 is default for HTTP): */
  WebServer webserver(PREFIX, 80);
  
  /*  */
  portENTER_CRITICAL();
  {
    /* start the Ethernet connection and the server */
    Ethernet.begin(mac, ip);
    
    /* web server related */
    
    /* setup our default command that will be run when the user accesses
     * the root page on the server */
    webserver.setDefaultCommand(&vHomeCmd);
  
    /* setup our default command that will be run when the user accesses
     * a page NOT on the server */
    webserver.setFailureCommand(&vFailCmd);
  
    /* run the same command if you try to load /index.html, a common
     * default page name */
    webserver.addCommand("message.xml",  &vXmlCmd);
    webserver.addCommand("index.html",   &vHomeCmd);
    webserver.addCommand("setup.html",   &vSetupCmd);
    webserver.addCommand("units.html",   &vUnitsCmd);
    webserver.addCommand("serial.html",  &vSerialCmd);
    webserver.addCommand("network.html", &vNetworkCmd);
    webserver.addCommand("status.html",  &vStatusCmd);
  
    /* start the webserver */
    webserver.begin();
  }
  portEXIT_CRITICAL();

  /* Cycle for ever, delaying then checking all the other tasks are still
     operating without error. */
  for( ;; ) {
    char buff[64];
    int len = 64;
    
    /* process incoming connections one at a time forever */
    webserver.processConnection(buff, &len);
  }
}

int main(void) {

  /* init mcu */
  init();
  
  /* init net-sensor to defaults */
  vInitConfig();
  
  // Pin change interrupt control register - enables interrupt vectors
  // Bit 2 = enable PC vector 2 (PCINT23..16)
  // Bit 1 = enable PC vector 1 (PCINT14..8)
  // Bit 0 = enable PC vector 0 (PCINT7..0)
  //PCICR |= (1 << PCIE0);
    
  // Pin change mask registers decide which pins are enabled as triggers
  //PCMSK0 |= (1 << PCINT5);

  // enable interrupts
  //interrupts();

  
  /* create tasks */
  xTaskCreate(vShtReadTask, (signed portCHAR *) "ShtRead", 304, NULL, NORMAL_PRIORITY, &xShtReadHandle);
  xTaskCreate(vMsReadTask,  (signed portCHAR *) "MsRead",  304, NULL, NORMAL_PRIORITY, &xMsReadHandle);
  xTaskCreate(vNetSvcTask,  (signed portCHAR *) "NetSvc",  700, NULL, NORMAL_PRIORITY, &xNetSvcHandle);
  xTaskCreate(vPrintTask,   (signed portCHAR *) "SPrint",  208, NULL, NORMAL_PRIORITY, NULL);
  
  /* start scheduler */
  vTaskStartScheduler();
  
  /* will only get here if there was insufficient memory  */
  for( ;; );
  
  return 1;
}

DuinOS.h
Code:
#ifndef DuinOS__h
#define DuinOS__h

#ifndef FREERTOS_ARDUINO
  #define FREERTOS_ARDUINO 1
#endif

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdlib.h>
#include <string.h>

//#ifdef GCC_MEGA_AVR
/* EEPROM routines used only with the WinAVR compiler. */
#include <avr/eeprom.h>
//#endif

/* Scheduler include files. */
#include "DuinOS/FreeRTOS.h"
#include "DuinOS/task.h"

#ifdef __cplusplus
} // extern "C"
#endif

//extern unsigned portBASE_TYPE mainLoopPriority;

//In small devices, we use only 3 priorities:
#define LOW_PRIORITY (tskIDLE_PRIORITY)
#define NORMAL_PRIORITY (tskIDLE_PRIORITY + 1)
#define HIGH_PRIORITY (tskIDLE_PRIORITY + 2)

// leave this for arduino libraries
#define delay(ticks) vTaskDelay(ticks)

#endif

main.cpp (just saves you from having to include header files but this file can be removed altogether)
Code:
#include <WProgram.h>

// add DuinOS support

#include "DuinOS.h"

Next is to get serial and Ethernet working using Interrupts to take full advantage of the RTOS.

Well that's all for now.
9  Using Arduino / Sensors / Re: SDI-12 compatibility on: February 24, 2011, 07:11:33 pm
I guess I am curious why you would want to interface an SDI-12 sensor to an Arduino. 

SDI-12 sensors have their own MCU, most pre-process measurements already (e.g. smp, avg, min, max, etc.) which can be called using the SDI protocol based on how the manufacturer has it configured and typically support other output types e.g. RS232/485.  SDI-12 is great for low powered applications and supports daisy chaining of sensors as the protocol supports sensor addressing.  It's a slick protocol developed by Eric Campbell of Campbell Scientific, worked for the company, and have used it frequently (sensor & data-logger development).

If your an intermediate programmer I would suggest polling the sensor via RS232.  Check the sensor because some support TTL, if thats the case, use the SoftSerial library and two IO ports.

10  Development / Other Software Development / Re: Agentuino - A lightweight SNMP Agent on: February 02, 2011, 06:47:58 pm
yesyes the short answer is no.  

We should probably clear the incoming buffer and send nothing back if it isn't a valid SNMP packet.  The problem with clearing the buffer is if another UDP protocol library is used in conjunction with the SNMP library.  I'll need to look into better handling of invalid packets but at least the "quick fix" you suggested seems to work.

Our alpha release works fairly well considering it's footprint size (Flash/RAM) and the amount of time put into it based on the testing I've done to date.  I really want to get the get-next requests working and the more I dive into implementing this functionality, more will change with the library.
11  Development / Other Software Development / Re: Agentuino - A lightweight SNMP Agent on: February 02, 2011, 03:35:26 pm
thanks for sharing yesyes.
12  Development / Other Software Development / Re: Agentuino - A lightweight SNMP Agent on: February 02, 2011, 12:16:00 pm
For those of you have been using the library I found bug and offering a correction that will prevent the MCU from hanging with an unknown request.

As per included sample sketch with the library, please see modifications, as per included code:
Code:
void pduReceived()
{
  SNMP_PDU pdu;
  //
  #ifdef DEBUG
    Serial << F("UDP Packet Received Start..") << F(" RAM:") << freeMemory() << endl;
  #endif
  //
  api_status = Agentuino.requestPdu(&pdu);
  //
  if ( pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GET_NEXT || pdu.type == SNMP_PDU_SET
    && pdu.error == SNMP_ERR_NO_ERROR && api_status == SNMP_API_STAT_SUCCESS ) {
    //
    pdu.OID.toString(oid);
    //
    Serial << "OID: " << oid << endl;
    //
    if ( strcmp_P(oid, sysDescr ) == 0 ) {
// handle sysDescr (set/get) requests
if ( pdu.type == SNMP_PDU_SET ) {
  // response packet from set-request - object is read-only
  pdu.VALUE.encode(SNMP_SYNTAX_NULL);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = SNMP_ERR_READ_ONLY;
} else {
  // response packet from get-request - locDescr
  status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locDescr);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
}
//
#ifdef DEBUG
  Serial << F("sysDescr...") << locDescr << F(" ") << pdu.VALUE.size << endl;
#endif
    } else if ( strcmp_P(oid, sysUpTime ) == 0 ) {
// handle sysName (set/get) requests
if ( pdu.type == SNMP_PDU_SET ) {
  // response packet from set-request - object is read-only
  pdu.VALUE.encode(SNMP_SYNTAX_NULL);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = SNMP_ERR_READ_ONLY;
} else {
  // response packet from get-request - locUpTime
  status = pdu.VALUE.encode(SNMP_SYNTAX_TIME_TICKS, locUpTime);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
}
//
#ifdef DEBUG
  Serial << F("sysUpTime...") << locUpTime << F(" ") << pdu.VALUE.size << endl;
#endif
    } else if ( strcmp_P(oid, sysName ) == 0 ) {
// handle sysName (set/get) requests
if ( pdu.type == SNMP_PDU_SET ) {
  // response packet from set-request - object is read/write
  status = pdu.VALUE.decode(locName, strlen(locName));
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
} else {
  // response packet from get-request - locName
  status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locName);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
}
//
#ifdef DEBUG
  Serial << F("sysName...") << locName << F(" ") << pdu.VALUE.size << endl;
#endif
    } else if ( strcmp_P(oid, sysContact ) == 0 ) {
// handle sysContact (set/get) requests
if ( pdu.type == SNMP_PDU_SET ) {
  // response packet from set-request - object is read/write
  status = pdu.VALUE.decode(locContact, strlen(locContact));
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
} else {
  // response packet from get-request - locContact
  status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locContact);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
}
//
#ifdef DEBUG
  Serial << F("sysContact...") << locContact << F(" ") << pdu.VALUE.size << endl;
#endif
    } else if ( strcmp_P(oid, sysLocation ) == 0 ) {
// handle sysLocation (set/get) requests
if ( pdu.type == SNMP_PDU_SET ) {
  // response packet from set-request - object is read/write
  status = pdu.VALUE.decode(locLocation, strlen(locLocation));
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
} else {
  // response packet from get-request - locLocation
  status = pdu.VALUE.encode(SNMP_SYNTAX_OCTETS, locLocation);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
}
//
#ifdef DEBUG
  Serial << F("sysLocation...") << locLocation << F(" ") << pdu.VALUE.size << endl;
#endif
    } else if ( strcmp_P(oid, sysServices) == 0 ) {
// handle sysServices (set/get) requests
if ( pdu.type == SNMP_PDU_SET ) {
  // response packet from set-request - object is read-only
  pdu.VALUE.encode(SNMP_SYNTAX_NULL);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = SNMP_ERR_READ_ONLY;
} else {
  // response packet from get-request - locServices
  status = pdu.VALUE.encode(SNMP_SYNTAX_INT, locServices);
  pdu.type = SNMP_PDU_RESPONSE;
  pdu.error = status;
}
//
#ifdef DEBUG
  Serial << F("locServices...") << locServices << F(" ") << pdu.VALUE.size << endl;
#endif
    } else {
// oid does not exist
//
// response packet - object not found
pdu.VALUE.encode(SNMP_SYNTAX_NULL);
pdu.type = SNMP_PDU_RESPONSE;
pdu.error = SNMP_ERR_NO_SUCH_NAME;
    }
    //
    Agentuino.responsePdu(&pdu);
  }
  //
  Agentuino.freePdu(&pdu);
  //
  Serial << "UDP Packet Received End.." << " RAM:" << freeMemory() << endl;
}

By adding "pdu.VALUE.encode(SNMP_SYNTAX_NULL);" it will send a response to the Manager either way and prevent the MCU from hanging.

More changes are planned and required in order to support Get-Next functionality, so stay tuned for improvements.  Again, developers are welcome to contribute, please contact me if your interested.
13  Development / Other Software Development / Agentuino - A lightweight SNMP Agent on: February 02, 2011, 12:09:24 pm
Not certain how we are supposed to port old subject and posted chains.  So a new one has been created in continuation of the Agentuino Library.

The original community interactions can be found here; http://arduino.cc/forum/index.php/topic,38103.msg282272.html#msg282272

Project source code is hosted on Google and can be located here; http://code.google.com/p/agentuino/

Welcome to the new forum all.
14  Forum 2005-2010 (read only) / Syntax & Programs / Re: String comparison on: September 12, 2010, 10:34:43 am
As mentioned in a previous post; when comparing strings in C you can't use == or conditional operators like you would with numeric values.  The string library may have a built-in function to compare it's string to another, not certain of that, but you may want to take a look here: http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#ga46f3cbd2de457c0fb340a1f379fc33ba

The function you want to use, in your case, is "strcmp" which is string compare.

Regards,

Eric



15  Forum 2005-2010 (read only) / Syntax & Programs / Re: Convert Long to String on: August 30, 2010, 08:29:14 pm
Instead of calling sprintf you could also use ltoa which consumes less resources and use the Streaming library if a single line or string concatenation is desired.

Code snippet:
Code:
 char buf[50];
  
  unsigned long testID = 1716526225;
  ltoa(testID, buf, 10);  // 10 is the base value not the size - look up ltoa for avr
  Serial << "GET /testID=" << testID << " HTTP/1.0" << endl; // Streaming.h
  delay( 1000 );

or

Code:
 char buf[50];
  
  unsigned long testID = 1716526225;
  ltoa(testID, buf, 10);  // 10 is the base value not the size - look up ltoa for avr
  Serial.print("GET /testID=");
  Serial.print(testID);
  Serial.println(" HTTP/1.0");
  delay( 1000 );

Cheers,

Eric
Pages: [1] 2 3 ... 5