Show Posts
Pages: 1 ... 13 14 [15]
211  Forum 2005-2010 (read only) / Syntax & Programs / Re: Problems with pointers for "Linked Lists" on: June 29, 2010, 10:52:37 pm
Mike,

When the loop goes around for a second time, I think that a reallocation of memory for the structures would be an interesting problem.

I suppose that I am still getting used to the loop() function in place of main().

212  Forum 2005-2010 (read only) / Syntax & Programs / Re: Problems with pointers for "Linked Lists" on: June 29, 2010, 08:43:15 pm
Thanks Mike,

"Great minds think alike", as I had added that property before finishing up last night.  

It's good to see that people are playing at home!

Here is what I ended up with:
Code:
/*******************************************************************
 * Program Name: Create XML Node
 * Author: LDU (2010)
 *
 * Language: Arduino C/C++
 *
 * Copywrite: Beerware
 * (If you like the program feel free to use it-
 * And if you meet me in a pub some time, you can
 * buy me a beer.)
 *
 * Description:
 * Creates a list that can be used to create, insert, delete and
 * modify an XML file.
 *
 * -A list element is inserted at the end by using AddNode();
 * -The list created is printed by PrintTree();
 * -The program is stopped with StopProgram().
 *
 ********************************************************************/
/********************************************************************
 * Included headers
 ********************************************************************/
#include <stdio.h>
#include <string.h>
/********************************************************************/

/********************************************************************
 * Global structures
 ********************************************************************/
struct XML_Node{
  char *name;
  char *data;
  struct XML_Node *previous;
  struct XML_Node *next;
  struct XML_Node *parent;
};
/********************************************************************/

/********************************************************************
 * Global Variables
 ********************************************************************/
struct XML_Node *RootNode; //List 1 start & finish
struct XML_Node *LastNode;

/************************************************/

/************************************************/

void setup(){

  Serial.begin(9600);

  RootNode = LastNode = NULL; //Initialise start and finish list pointers

}
void loop(){

  /*****************************************************************/
  struct XML_Node Node_1;
  struct XML_Node Node_2;
  struct XML_Node Node_3;

  static char str_Name[] = "First";
  static char str_Name2[] = "second";
  static char str_Name3[] = "third";
  static char str_Data[] = "Test Data";

  AddNode(&Node_1, NULL, str_Name, str_Data, &RootNode, &LastNode);

  AddNode(&Node_2, &Node_1, str_Name2, str_Data, &RootNode, &LastNode);

  AddNode(&Node_3, &Node_2, str_Name3, str_Data, &RootNode, &LastNode);

  StopProgram(0);

  /*****************************************************************/
}

/*******************************************************************
 * Create a new XML node
 ********************************************************************
 * Format:
 * AddNode(Element As *XML_Node, Parent Node As *XML_Node,
 * Name As *char, Data As *char, List Root Element As **XML_NODE,
 * Lists Last Node As **XML_Node) Handles creating a new XML element
 ********************************************************************/
void AddNode(struct XML_Node *i,   //New element >> (i)nput
struct XML_Node *ParentNode,       //points to parent node
char *NodeName, char *NodeData,    //pointers to the name and data
struct XML_Node **RootNode,        //first element on list
struct XML_Node **LastNode) {      //Last element on list

  struct XML_Node *old, *p;

  //If there is an input error, exit function
  if(!RootNode || !LastNode|| !NodeName || !NodeData) return;

  i->name = NodeName;  //Store data and name locations
  i->data = NodeData;

  if(!*LastNode) { //if empty list, this is the root element

    i->next = NULL;        //Setup information for element
    i->previous = NULL;
    i->parent = NULL;

    *LastNode = i;        //Setup infomation for list
    *RootNode = i;

    return;
  }

  //At this point, if there is no Parent, do not
  //make node- exit function
  if(!ParentNode) return;

  //Start search at top of list
  p = *RootNode;
  old = NULL;

  while(p){ //find last element
    old = p;
    p = p->next;
  }

  old->next = i;         //put on end
  i->next = NULL;        //Setup informaiton for element
  i->previous = old;
  i->parent = ParentNode;

  *LastNode = i;         //Setup information for list

}

/*****************************************************************
 * Prints out to screen the list tree, starting at "StartNode"
 *****************************************************************/
void PrintTree(struct XML_Node *StartNode) {

  //if no input, exit right away
  if(!StartNode) return;

  struct XML_Node *info;  //point to start of printing
  info = StartNode;    

  while(info) {           //Go through list in order and print

    Serial.print("</PrintList node=\"");  
    Serial.print(info->name);
    Serial.print("\" Next=");
    Serial.print("\"");
    Serial.print(info->next->name);
    Serial.print("\"");
    Serial.print(" Parent=");
    Serial.print("\"");
    Serial.print(info->parent->name);
    Serial.print("\"");
    Serial.println(">");

    info = info->next;
  }

}
/*****************************************************************/

/*****************************************************************
 * Stop program is used for stopping the program and displaying
 * final values
 *****************************************************************/
inline void StopProgram(char Position){

  //if a location specifier given, print it
  if(Position) Serial.println(Position, HEX);  

  //prompt user
  Serial.println("\nProgram Finished Running");

  //print results
  PrintTree(RootNode);

  //hold program here
  for(;;);
}
/*****************************************************************/

All the best.
213  Forum 2005-2010 (read only) / Syntax & Programs / Re: Problems with pointers for "Linked Lists" on: June 29, 2010, 06:46:32 am
Hey all,

I worked the problem out!!!

The problem was in the malloc().

The malloc() was there before the subroutine, when Node_x was a pointer, not literal XML_Node.  The Nodes where changed, but (for some unknown reason) I have kept the memory request in and overlooked it for hours at a time.

What was happening (for all those playing at home) was that the malloc() was over riding *i as a new entry.

smiley
214  Forum 2005-2010 (read only) / Syntax & Programs / Re: Problems with pointers for "Linked Lists" on: June 29, 2010, 06:07:37 am
Hey again,

I've worked out that the program works when "Node_1", "Node_2" and "Node_3" have their names and data pointers set outside the function AddNode().

ie.
Code:

AddNode(&Node_1, NULL, str_Name, str_Data, &RootNode, &LastNode);

  Node_1.name = str_Name; Node_1.data = str_Data;

This means that the problem is in the connection between the structures "Node_x" and the structure pointed to in AddNode()...

Question:
  • If the function can change the value of the pointers for next and previous, why can't it change the pointers for name and data?...

Any ideas?
[/list]
215  Forum 2005-2010 (read only) / Syntax & Programs / Problems with pointers for "Linked Lists" on: June 29, 2010, 05:07:57 am
Hello everyone,

I have spent a good afternoon trying to work this one out!

Basically, I'm trying to create an XML data structure using a Link-list with a "parent" property for each element.

The problem that I am having is that the structures "Node_1", "Node_2" and "Node_3" are not being changed in the "AddNode" function.  

The one thing that keeps letting me down is that the "parent" property is not remembering which element it is assigned.

desired output:

<!--Creating Root Element-->
<!--Creating non-root Element-->
<!--Creating non-root Element-->

Program Finished Running
</PrintList node="First" Next="second" Parent="">
</PrintList node="second" Next="third" Parent="First">
</PrintList node="third" Next="" Parent="First">


However, the "Parent" properties are not returning any data.

Code:
#include <stdio.h>

// Library to support string opperation
#include <string.h>

struct XML_Node{
  char *name;
  char *data;
  struct XML_Node *previous;
  struct XML_Node *next;
  struct XML_Node *parent;
};

struct XML_Node *RootNode;
struct XML_Node *LastNode;

 struct XML_Node Node_1;
 struct XML_Node Node_2;
 struct XML_Node Node_3;
  
  
/************************************************/

void setup(){

  Serial.begin(9600);

  RootNode = LastNode = NULL; //Initialise start and finish pointers

}
void loop(){

  /*****************************************************************/

  char str_Name[] = "First";
  char str_Name2[] = "second";
  char str_Name3[] = "third";
  char str_Data[] = "Test Data";

  AddNode(&Node_1, NULL, str_Name, str_Data, &RootNode, &LastNode);

  AddNode(&Node_2, &Node_1, str_Name2, str_Data, &RootNode, &LastNode);
  
  AddNode(&Node_3, &Node_1, str_Name3, str_Data, &RootNode, &LastNode);
  
 
  /*****************************************************************/
  StopProgram(0);
}
/*Create a new XML node*/
void AddNode(struct XML_Node *i,   //New element >>
struct XML_Node *ParentNode,       //points to parent node
char *NodeName, char *NodeData,    //pointers to the name and data
struct XML_Node **RootNode,        //first element on list
struct XML_Node **LastNode) {      //Last element on list

  struct XML_Node *old, *p;
    if(!RootNode) Serial.print("<!--ERROR: RootNode-->\n");
    if(!LastNode) Serial.print("<!--ERROR: LastNode-->\n");
    if(!NodeName || !NodeData) Serial.print("<!--ERROR: Input Strings-->\n");
    
  i = (struct XML_Node *)malloc(sizeof(struct XML_Node));
  if(!i) {
    return;  //if memory allocation didn't work, return error
  }

  i->name = NodeName;  //Store data and name locations
  i->data = NodeData;

  if(!*LastNode) { //if empty list, root element
    Serial.print("<!--Creating Root Element-->\n");
    i->next = NULL;
    i->previous = NULL;
    i->parent = NULL;

    *LastNode = i;
    *RootNode = i;

    return;
  }
  Serial.print("<!--Creating non-root Element-->\n");  
  if(!ParentNode) Serial.print("<!--ERROR: ParentNode-->\n");
  
  //Start at top of list
  p = *RootNode;
  old = NULL;

  while(p){ //find last element
    old = p;
    p = p->next;
  }

  old->next = i; //put on end
  i->next = NULL;
  i->previous = old;
  i->parent = ParentNode;
  
  *LastNode = i;
  
}

/*Prints out to screen the list tree, starting at "StartNode"*/
void PrintTree(struct XML_Node *StartNode) {

  if(!StartNode) return;

  struct XML_Node *info;

  info = StartNode;

  while(info) {

    Serial.print("</PrintList node=\"");  
    Serial.print(info->name);
    Serial.print("\" Next=");
    Serial.print("\"");
    Serial.print(info->next->name);
    Serial.print("\"");
    Serial.print(" Parent=");
    Serial.print("\"");
    Serial.print(info->parent->name);
    Serial.print("\"");
    Serial.println(">");

    info = info->next;
  }

}

inline void StopProgram(char Position){
  if(Position) Serial.println(Position, HEX);
  Serial.println("\nProgram Finished Running");
  PrintTree(RootNode);
  for(;;);
}


Any help would be very appreciated.

smiley
216  Forum 2005-2010 (read only) / Development / Dynamic allocation of memory on: August 17, 2010, 08:04:38 am
I have been looking a bit into "__malloc_heap_end" lately, and I think that there might me a way to malloc some memory (responsibly).

If anyone is curious and wants to help me look into this, start by reading http://www.nongnu.org/avr-libc/user-manual/malloc.html.

Especially this bit:
"If __malloc_heap_end is 0, the allocator attempts to detect the bottom of stack in order to prevent a stack-heap collision when extending the actual size of the heap to gain more space for dynamic memory"

If anyone has done any research on this matter, please feel free to post some knowledge!
217  Forum 2005-2010 (read only) / Development / Re: Reference variable with string on: August 17, 2010, 08:37:03 am
If you use malloc, you run the risk of loosing info from your stack.

You can use it, but you should never use it.
218  Forum 2005-2010 (read only) / Bugs & Suggestions / Example code on site on: July 27, 2010, 11:15:35 pm
I don't know if this is the right room, but there seems to be some trouble with the example code in the learning>examples>Analogue section.

Would someone be able to chase that up?
219  Forum 2005-2010 (read only) / Exhibition / Advanced version of Serial Out on: August 16, 2010, 07:49:35 am
Hey all,

I had a few friends ask me about a state machine that I made for the serial out example.  

I was new to the Arduino, and I wanted to play around with the 'serial' class.

... So this is for them, but I'm happy for any comments/suggestions...

Code:
/*****************************************************
 * SUMMARY
 *****************************************************/
//LDU
/*
 This program is designed to print out
 all the ASCII keys as an intro to
 Serial communication.
 
 It is based on <arduino.cc/en/Tutorial/ASCIITable>
 and been carefully studied for my understanding, and
 then updated to enclude some more advanced techniques.
 
 ASCII table
 
 Prints out byte values in all possible formats:  
 as raw binary values
 as ASCII-encoded decimal, hex, octal, and binary values
 
 For more on ASCII, see http://www.asciitable.com and
 http://en.wikipedia.org/wiki/ASCII
 
 */

/*****************************************************
 * PROPERTIES
 *****************************************************/
//Functions in project
void PrintMenu(void);
void GetInputState(void);
void GetInputState(void);
void SetupPrintingInstance(struct PrintingInstance *PrintWindow, int Start, int Finish);
void PrintLine(struct PrintingInstance *PrintWindow);

//Constants for project
const int FirstPrintableChar = '!';
const int LastPrintableChar = '~';

const int FirstNumber = '0';
const int LastNumber = '9';

const int FirstLowerLetter = 'a';
const int LastLowerLetter = 'z';

const int FirstCapitalLetter = 'A';
const int LastCapitalLetter = 'Z';


//Enumerations for program
//(This is a customised variable type)
enum State //What State the program is in
{
  InitialiseObjects,
  PromptPrintingList,
  WaitingForInput,
  PrintAllChar,
  PrintNumbers,
  PrintLower,
  PrintCapital,
  AfterPrintingToScreen,
  unknown
};

//Objects for program
struct PrintingInstance //A window of characters to print
{
  int StartingChar;
  int FinishChar;
  int CurrentChar;
};

//Declare printing window object
PrintingInstance FullPrintingWindow;
PrintingInstance NumberPrintingWindow;
PrintingInstance LowerPrintingWindow;
PrintingInstance CapitalPrintingWindow;

//Declare Program state
State PrintingState;

//Declare variable for user input
int UserInput;

/*****************************************************
 * SETUP
 *****************************************************/

void setup()
{
  //Set up port speed
  Serial.begin(9600);

  //Prints title which explains what is to be explained
  Serial.println("ASCII Table ~ Character Map");

  //Set up initial state
  PrintingState = InitialiseObjects;

}

/*****************************************************
 * MAIN STATE MACHINE
 *****************************************************/

void loop()
{
  switch(PrintingState)
  {
  case InitialiseObjects:

    //initialise "FullPrintingWindow"
    SetupPrintingInstance(&FullPrintingWindow, FirstPrintableChar, LastPrintableChar);

    //initialise "NumberPrintingWindow"
    SetupPrintingInstance(&NumberPrintingWindow, FirstNumber, LastNumber);

    //initialise "LowerPrintingWindow"
    SetupPrintingInstance(&LowerPrintingWindow, FirstLowerLetter, LastLowerLetter);

    //initialise "CapitalPrintingWindow"
    SetupPrintingInstance(&CapitalPrintingWindow, FirstCapitalLetter, LastCapitalLetter);

    break;

  case PromptPrintingList:

    //Prompt user with options
    PrintMenu();

    break;  

  case WaitingForInput:

    GetInputState();

    break;

  case PrintAllChar:

    //Print all characters
    PrintLine(&FullPrintingWindow);

    break;

  case PrintNumbers:

    //Print all numbers
    PrintLine(&NumberPrintingWindow);

    break;

  case PrintLower:

    //Print all lower letters
    PrintLine(&LowerPrintingWindow);

    break;

  case PrintCapital:

    //Print all Capital Letters
    PrintLine(&CapitalPrintingWindow);

    break;

  case AfterPrintingToScreen:
  
    //Do not do anything
    
    break;

  default:
  
    //Restore nonprinting state
    PrintingState = AfterPrintingToScreen;
    
    break;

  }

}

/*****************************************************
 * METHODS
 *****************************************************/

void SetupPrintingInstance(struct PrintingInstance *PrintWindow, int Start, int Finish)
{
  // Address of a PrintingInstance object, start position
  // and finish position is passed into function

  //Set up domain of Charactors wanted to print
  PrintWindow->StartingChar = Start;
  PrintWindow->FinishChar = Finish;
  PrintWindow->CurrentChar = Start;

  //Update State
  PrintingState = PromptPrintingList;

}

void PrintMenu()
{
  //Menu for user to select from:
  Serial.println("What would you like to see?");
  Serial.println("1 - All printable ASCII characters");
  Serial.println("2 - All numbers");
  Serial.println("3 - All lower case letters");
  Serial.println("4 - All capital letters");

  //Update State
  PrintingState = WaitingForInput;

}

void GetInputState()
{
  int IncomingCharacter;

  while(Serial.available() == 0)
  {
    //Do Nothing...
  }

  //Get users incoming character
  IncomingCharacter = Serial.read();

  //match input to printing state
  switch(IncomingCharacter)
  {
  case '1':

    //User wants to print out all ASCII Characters
    PrintingState = PrintAllChar;

    break;

  case '2':

    //User wants to print out all ASCII Numbers
    PrintingState = PrintNumbers;

    break;

  case '3':

    //User wants to print out all ASCII lower letters
    PrintingState = PrintLower;

    break;

  case '4':

    //User wants to print out all ASCII Capital Letters
    PrintingState = PrintCapital;

    break;

  default:

    //User has made an error
    PrintingState = WaitingForInput;

    break;
  }
}

void PrintLine(struct PrintingInstance *PrintWindow)
{
  //Address of a PrintingInstance object is passed into function

  //Prints a line based on what character is in
  //object currently.

  //Note that "->" is used when dealing with structure elements
  //and pointers.

  //Declare what first print is going to be
  Serial.print("Character: ");
  //Print out current byte
  Serial.print(PrintWindow->CurrentChar, BYTE);

  //Declare what the second print will be
  Serial.print(", Dec: ");
  //Print out byte as Decimal (base 10)
  //(Note that the ", DEC" is not actually
  //needed by default)
  Serial.print(PrintWindow->CurrentChar, DEC);

  //Same with third print
  Serial.print(", Hex: ");
  Serial.print(PrintWindow->CurrentChar, HEX);

  //Same with forth print
  Serial.print(", Oct: ");
  Serial.print(PrintWindow->CurrentChar, OCT);

  //Same with fith print
  Serial.print(", Binary: ");
  Serial.println(PrintWindow->CurrentChar, BIN);

  //If last character is found, switch to
  //a non printing state
  if(PrintWindow->CurrentChar == PrintWindow->FinishChar)

  {
    PrintingState = WaitingForInput;
  }

  //Increment current ASCII Byte
  PrintWindow->CurrentChar++;

}


And I have never posted anything on exhibition, so I thought that it would be different!

smiley
Pages: 1 ... 13 14 [15]