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. // 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. 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
|
|
|
|
|
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=1256745982Well 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: 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 #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) #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.
|
|
|
|
|
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: 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.
|
|
|
|
|
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: 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 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
|
|
|
|
|