Show Posts
|
|
Pages: [1] 2
|
|
2
|
Using Arduino / Programming Questions / Re: Working with array of strings, PROGMEM question
|
on: February 02, 2013, 12:29:13 pm
|
|
Thank you very much indeed guys for sharing your knowledge and opinion. I can see I am simply scratching the surface of the Progmem and strings, I will solder together an new mini OLED tonight and will see if everything works correctly.
So far I have been only compiling to check that everything works, strange enough Arduino will always give me the same randomly calculated names and last names, is that normal? I mean it puts together names and last names once, then if I unplug it and plug it back either some minutes later or the day after, it gives me back names and last names with the same order it did before, as if it can only ramdomly calculate names and last names once.
Any ideas about it?
Thanks!
Elso
|
|
|
|
|
4
|
Using Arduino / Programming Questions / Re: Working with array of strings, PROGMEM question
|
on: January 30, 2013, 04:35:15 am
|
Okay... I still seem to have a problem understanding the strings being 8 characters long, sorry, just being thick probably  At the moment, looking at the tutorial I have created two lists and a buffer into which I copy one string at time that is being concatenated into a char, I have rewritten the previous code like this: // include the library code: #include <Adafruit_CharacterOLED.h> #include <avr/pgmspace.h>
// initialize the library with the numbers of the interface pins Adafruit_CharacterOLED lcd(6, 7, 8, 9, 10, 11, 12);
prog_char string_0[] PROGMEM = "MARK"; // "String 0" etc are strings to store - change to suit. prog_char string_1[] PROGMEM = "FRANCIS"; prog_char string_2[] PROGMEM = "JOHN"; prog_char string_3[] PROGMEM = "ANDREW"; prog_char string_4[] PROGMEM = "ROBERT"; prog_char string_5[] PROGMEM = "SEAN";
prog_char string_6[] PROGMEM = "HAYES"; // "String 0" etc are strings to store - change to suit. prog_char string_7[] PROGMEM = "LUDWIG"; prog_char string_8[] PROGMEM = "HARRISON"; prog_char string_9[] PROGMEM = "GRAND"; prog_char string_10[] PROGMEM = "SALTER"; prog_char string_11[] PROGMEM = "BOND";
// Then set up a table to refer to your strings.
PROGMEM const char *string_table1[] = // change "string_table" name to suit { string_0, string_1, string_2, string_3, string_4, string_5 };
PROGMEM const char *string_table2[] = // change "string_table" name to suit { string_6, string_7, string_8, string_9, string_10, string_11}; char buffer[30]; // make sure this is large enough for the largest string it must hold
long randNames; // random word taken from the group names long randLastnames; // random last name char finalWord[40]; // enough room for all strings together int myLenght; // lenght of the final word //int myCentre; // coordinates to place the final word in the centre
char* mySpace = " ";
void setup(){ Serial.begin(9600); }
void loop(){ randNames = random (320); //picks a synonym randLastnames = random (320); //picks an adjective finalWord[0] = 0; // start with a null string: strcpy_P(buffer, (char*)pgm_read_word(&(string_table1[randNames]))); strcat (finalWord, buffer); //add third string strcat(finalWord, mySpace); // add second string, the empty space string strcpy_P(buffer, (char*)pgm_read_word(&(string_table2[randLastnames]))); strcat(finalWord, buffer); // add first string myLenght = strlen(finalWord); Serial.println(finalWord); } This should give me the final word as a result of Names + Lastnames, one at time, I guess. Instead I cannot see anything printed on the serial monitor, for the moment I am not trying to write to the OLED. Can you spot if there is anything wrong in it? Many thanks! Elso
|
|
|
|
|
6
|
Using Arduino / Programming Questions / Working with array of strings, PROGMEM question
|
on: January 29, 2013, 05:02:53 pm
|
Hi there, following my previous topic ( http://arduino.cc/forum/index.php/topic,145342.msg1091993.html#msg1091993) regarding the maximum number of strings I can place in an array, I am trying to use the PROGMEM to store the string arrays I have in the Flash memory; the main problem is that I don't k ow if this is the right procedure to follow in my case. What I am trying to achieve is: to have two arrays containing strings, about 300 strings each, each containing between 3 to 8 letters. Each time the sketch run, two strings are randomly selected from the two arrays (one pulled from each one of them); then they are concatenated and visualised on an OLED display, using the Adafruit library ( https://github.com/ladyada/Adafruit_CharacterOLED). As those are too many strings and I already had some memory issues with my script (I am using an Arduino Mega 2560) I would like to move those strings to the flash memory. I went to the PROGMEM tutorial page ( http://www.arduino.cc/en/Reference/PROGMEM) but it seems to me that I need to copy the string table / array to the RAM buffer. My questions are: - do I need to copy the entire array or simply the string randomly selected? - do I need to clear that buffer once I don't need the string anymore to make space for another one? Many thanks for your help, I am attaching a shorter version of my code // include the library code: #include <Adafruit_CharacterOLED.h>
// initialize the library with the numbers of the interface pins Adafruit_CharacterOLED lcd(6, 7, 8, 9, 10, 11, 12);
long randNames; // random word taken from the group male names long randLastnames; // random last name char finalWord[40]; // enough room for all strings together int myLenght; // lenght of the final word
char* maleNames[]={"FRANK", "JOHN", "MARK", "LORIS", "MICHAEL", "...., };
char* maleLastnames[]={"STEIN", "OLLIS", "GRAND", "MERLIN", "KRANZ", "...
};
char* mySpace = " ";
void setup(){ Serial.begin(9600); }
void loop(){ randNames = random (320); //picks a random name randLastnames = random (320); //picks a random last name finalWord[0] = 0; // start with a null string: strcat(finalWord, maleLastnames[randLastnames]); // add first string strcat(finalWord, mySpace); // add second string, the empty space string strcat (finalWord, maleNames[randNames]); //add third string myLenght = strlen(finalWord);
if (myLenght < 16) {// if the final word doesn't exceed 16 spaces lcd.setCursor(0, 0); //positions the cursor on the first row lcd.print(finalWord); //prints the word picked from the group
delay(10000); // wait a bit for ppl to read lcd.clear(); // clears the display delay(5000); // dark/empty display } }
|
|
|
|
|
8
|
Using Arduino / Project Guidance / Re: Max number of Strings in a char array
|
on: January 27, 2013, 07:23:56 pm
|
Thanks Paul, ops, yes, indeed I meant strings, not Strings...  The length of each string varies from 2 to 10 characters. Since my arrays of strings won't change after the program runs, I guess I should store them both in the Flash memory through the PROGMEM, am I right? Best Elso
|
|
|
|
|
9
|
Using Arduino / Project Guidance / Max number of Strings in a char array
|
on: January 27, 2013, 04:36:46 pm
|
|
Hi there, I am controlling an external LCD display, I have two char arrays with words, I randomly extrapolate words off each one of them, the concatenate them and visualise them on the display. I was wondering, how many can I store in the Arduino Mega (which will run without laptop) before having to use external RAM? Also, as I haven't used such RAM before, could you please advice what is the one I should buy?
Many thanks
Best
Elso
|
|
|
|
|
11
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Processing to Arduino over remote network
|
on: November 25, 2012, 04:23:33 am
|
Hi zoomkat, when you say to have something at the remote address to update the dyn dns site of the current IP assignment. do you mean that I have to have the dyn dns updater running on a computer at the remote location? Or, as you mention the router, should I just ask the administrator of the remote network to port forward the address of my arduino and get it updated automatically it every now and then so I can access it when I am away? I am afraid I am a bit confused, just going through dynDNS's guidelines. I have created a new host name with dynDNS and I have assigned the IP of the Arduino to it, however it shows the router's address whenever I run the updater. Is this the right procedure? Thanks for your help!
|
|
|
|
|
12
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Processing to Arduino over remote network
|
on: November 24, 2012, 12:03:30 pm
|
And then the Arduino through Ethernet. By the way... on the Arduino I am receiving some strange reading when I try translate the string coming from Processing. Am I doing a wrong interpretation of that string into an integer? #include <SPI.h> // needed for Arduino versions later than 0018 #include <Ethernet.h> #include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008 #define numBufSize 3
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0x90, 0xA2, ... }; //MAC address of the shield to be found on the box of the shield IPAddress ip(192, 168, 1, 167); //IP address of Arduino on the Network
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP EthernetUDP Udp;
long sequenceDelay = 500; long flashDelay = 500;
boolean REL1state = true; // the RELAY will turn ON in the first iteration of loop() boolean REL2state = true; boolean REL3state = true; boolean REL4state = true;
long waitUntil1 = 0; // the seed will determine time flashing of the RELAYS long waitUntil2 = 3000; long waitUntil3 = 3000; long waitUntil4 = 3000;
// These are motor variables int r1val = 0; //variable controlling position of motor 1 int oldr1val = 0; // old variable controlling position of motor 1 int r2val = 0; //variable controlling position of motor 2 int oldr2val = 0; // old variable controlling position of motor 2 int r3val = 0; //variable controlling position of motor 3 int oldr3val = 0; // old variable controlling position of motor 3 int r4val = 0; //variable controlling position of motor 3 int oldr4val = 0; // old variable controlling position of motor 3
boolean startLine = true; // this controls that all motors are reset to '0' at the beginning, // this function happens at the end of the code
char numStr[numBufSize] = { '0','1', '2' }; // just as an example
int ledState = LOW; // ledState used to set the LED long previousMillis = 0; // will store last time LED was updated
void setup() { // start the Ethernet and UDP: Ethernet.begin(mac,ip); Udp.begin(localPort);
Serial.begin(9600); //or 9600? pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); delay(4000); //Check that all relays are inactive at Reset }
void loop() { // if there's data available, read a packet int packetSize = Udp.parsePacket(); if(packetSize) { Serial.print("Received packet of size "); Serial.println(packetSize); Serial.print("From "); IPAddress remote = Udp.remoteIP(); for (int i =0; i < 5; i++) { Serial.print(remote[i], DEC); if (i < 3) { Serial.print("."); } } Serial.print(", port "); Serial.println(Udp.remotePort());
// read the packet into packetBufffer Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); // Serial.println("Contents:"); // Serial.println(packetBuffer); // Convert decimal string in numStr to an unsigned integer in num. // The string is in a fixed size buffer. // There is no checking for invalid digit characters or number too large. unsigned long num = 0; for (int i = 0; i < numBufSize; i++) { num = num * 10 + (packetBuffer[i] - '0'); } // Serial.println(num); if (packetBuffer[0]=='P') { r1val=int(num - 3200); } if (packetBuffer[0]=='Q') { r2val=num - 3300; } if (packetBuffer[0]=='R') { r3val=num - 3400; // reads the value coming from Processing related to category 3 } if (packetBuffer[0]=='S') { r4val=num - 3500; } // Serial.print("Relays"); Serial.println(r1val); Serial.println(r2val); Serial.println(r3val); Serial.println(r4val);
digitalWrite(2, REL1state); // each iteration of loop() will set the IO pins, digitalWrite(3, REL2state); digitalWrite(5, REL3state); digitalWrite(6, REL4state); // checking to see if enough time has elapsed if (millis() >= r1val*500) { REL1state = !(REL1state); r1val += flashDelay; // this if-statement will not execute for another 1000 milliseconds } // keep in mind, waitUntil5 was already seeded with a value of 500 if (millis() >= r2val*500) { REL2state = !(REL2state); r2val += flashDelay;
} if (millis() >= r3val*500) { REL3state = !(REL3state); r3val += flashDelay;
} if (millis() >= r4val*500) { REL4state = !(REL4state); r4val += flashDelay;
} oldr1val = r1val; // stores the value of r1val oldr2val = r2val; // stores the value of r2val oldr3val = r3val; // stores the value of r3val oldr4val = r4val; // stores the value of r4val Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); Udp.write(ReplyBuffer); Udp.endPacket(); } }
With this type of relation Processing > Arduino I would like Processing to be able to control the second from a remote location. I hope this wan't too much information. many thanks
|
|
|
|
|
13
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Processing to Arduino over remote network
|
on: November 24, 2012, 12:03:06 pm
|
Anyway. The script in Processing at the moment does this: import hypermedia.net.*; UDP udp; // define the UDP object String feed = "http://news.google.com/...."; int interval = 5; // this variable will be used to retrieve content; int lastTime; // var to be used as the last time we fetched the content
// the 4 main categories of words to be found int categ4 = 0; //word4 int categ3 = 0; //word3 int categ2 = 0; //word2 int categ1 = 0; //word1
// variables that represent the four above mentioned categories
//Serial port; int c1; // preparing category 1 to be sent int c2; // preparing category 2 to be sent int c3; // preparing category 3 to be sent int c4; // preparing category 3 to be sent
String buffer = ""; // This accumulates characters coming from Arduino PFont font; // This visualisation needs a font to display the informations collected
void setup() { size(1200, 480); frameRate(10); // regulates the speed at which the code is played font = loadFont("Akkurat-12.vlw"); fill(60); textFont(font, 12); noStroke(); udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000 //udp.log( true ); // <-- printout the connection activity udp.listen( true ); // and wait for incoming message
lastTime = 1000; fetchData(); } void draw() { background(255); int n = (interval - ((millis()-lastTime)/500)); // timer c1 = categ1; // Prepares the values for each category to be sent to Arduino c2 = categ2; c3 = categ3; c4 = categ4; // println(c1); text("Data reading from CSS", 55, 40); // diagram of the categories text("Reading feed:", 55, 60); text(feed, 55, 80); text("Word 1", 55, 400); text(categ1, 55, 420); rect(55, 380, 150, categ1*(-2.5)); text("Word 2", 245, 400); text(categ2, 245, 420); rect(245, 380, 150, categ2*(-2.5)); text("Word 3", 435, 400); text(categ3, 435, 420); rect(435, 380, 150, categ3* (-2.5)); text("Word 4", 625, 400); text(categ4, 625, 420); rect(625, 380, 150, categ4* (-2.5));
if (n <= 0) { // It sends data to Arduino every 1 second fetchData(); lastTime = millis(); String ip = "192.168.1.167"; // the remote IP address int port = 8888; // the destination port String cone="P"+categ1; println(cone); udp.send(cone, ip, port ); // the message to send myDelay(250); String ctwo="Q"+c2; println(ctwo); udp.send(ctwo, ip, port ); // the message to send myDelay(250); String cthree="R"+c3; println(cthree); udp.send(cthree, ip, port ); // the message to send myDelay(250); String cfour="S"+categ4; println(cfour); udp.send(cfour, ip, port ); // the message to send myDelay(250);
if (port.available() > 0) { // this checks if there is data waiting int inByte = port.read(); // then it reads one byte if (inByte != 10) { // if byte is not newline buffer = buffer + char(inByte); // it adds it to the buffer } else { // when a newline reached, it processes the data if (buffer.length() > 1) { // it makes sure there is enough data // this chops off the last character buffer = buffer.substring(0, buffer.length() -1); //clean the buffer for the next read cycle buffer = ""; // it refreshes the port port.clear(); } } } }
void fetchData() { // the code uses these strings to parse the feed String data; String chunk; // it zeroes the counters categ3 = 0; categ3 = 0; categ2 = 0; categ1 = 0; try { URL url = new URL(feed); // An object that represents the URL URL url2 = new URL(feed2); // Another one for anothert website t connect to // it prepares a connection URLConnection conn = url.openConnection(); conn.connect(); // it connects to google website // it connects the data coming from the connection to a buffered // reader that reads the data one line at a time. URLConnection conn2 = url2.openConnection(); conn2.connect(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); BufferedReader in2 = new BufferedReader(new InputStreamReader(conn2.getInputStream())); // it reads each line from the feed while ( (data = in.readLine ()) != null) { StringTokenizer st = new StringTokenizer(data, "\"<>,.()[] ");// it breaks it down while (st.hasMoreTokens ()) { // each chunk of data is made lowercase chunk= st.nextToken().toLowerCase() ; // and then the words every time they are found they add 1 to the category if (chunk.indexOf("word4") >= 0) categ4++; // increment categ4 by 1 if (chunk.indexOf("word3) >= 0) categ3++; // increment categ3 by 1 if (chunk.indexOf("word2) >= 0) categ2++; // increment categ2 by 1 if (chunk.indexOf("word1) >= 0) categ1++; // increment categ1 by 1
// It sets 100 to be the maximum number of references considered if (categ4 > 99) categ4 = 99; if (categ3 > 99) categ3 = 99; if (categ2 > 99) categ2 = 99; if (categ1 > 99) categ1 = 99;
} catch (Exception ex) { // If there was an error, it stops the sketch ex.printStackTrace(); System.out.println("ERROR: "+ex.getMessage()); } }
void myDelay(int ms) //This a delay which will used after each category (c1, c2, c3, c4, c5) // is sent to Arduino { try { Thread.sleep(ms); } catch(Exception e){} }
void receive( byte[] data ) { // <-- default handler //void receive( byte[] data, String ip, int port ) { // <-- extended handler for(int i=0; i < data.length; i++) print(char(data[i])); println(); }
|
|
|
|
|
14
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Processing to Arduino over remote network
|
on: November 24, 2012, 12:02:38 pm
|
|
Hi Paul, I had Processing parsing a website (ie google.news), looking for some words.
Then passing the amount of words found to Arduino (via Serial port); Arduino was using those integers to switch on and off some relays. My laptop was connected to the Arduino via USB cable. As second step I added an Ethernet shield on the Arduino to basically do exactly the same thing but through Ethernet (UDP send/receive) rather than serial as I wanted the laptop to be physically disconnected from the board.
I am now trying to have the Arduino at a different place than my studio, with a different network than my LAN and I would like Processing to send groups of integers to Arduino, to be used to switch the relays on and off.
I thought about running the Processing app online and have Arduino listening to it, would that be the case of having Arduino as a Web Client? I am still getting to know Ethernet and Arduino. I would consider all options available, would love to go for the simplest as I am still learning how to code properly.
|
|
|
|
|
15
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Processing to Arduino over remote network
|
on: November 24, 2012, 12:02:12 pm
|
|
Thanks Zoomkat, I have downloaded an app from the dyn site which should allow me to update the ip address at this location, I will give it a go, I am at the remote location now; will see what the IP adress here is and then probably tell the dyn to name it so that it will be updated from this position but I will always see it with the same name and address I guess. I will give it a go and let you know!
|
|
|
|
|