Avatar billede blod_1 Nybegynder
22. august 2009 - 22:31 Der er 24 kommentarer og
1 løsning

int imellem funktioner

Jeg har en class med funktioner, hvor positionerne for de forskellige servoer er registeret

namespace ServoController
{
    public class ServoControl
    {
        //Positions of servos stored here
        public int channel00 = 750;
        //som udgangangspunkt er positionen center, som er 750

        //herefter kommer funktionen som sender en ny position til servoen, og som samtidig sætter channel00, med den nye position

        public string SetServo(int channel, int ramp, int position, string function)
        {
            if (channel == 0)
            {
                channel00 = position;
            }
        }
    }
}

I min anden fil har jeg så dette

namespace SamplePlugin
{
    public partial class SamplePluginForm : Form
    {
        //ikke relevant kode klippet ud, hvor der bla bliver startet en timer

        private void channelsUpdate_Tick(object sender, EventArgs e)
        {
            progressBar00.Value = sc.channel00;
        }
    }
}

Mit problem her er så at det timeren får tilbage, er de 750 som jeg har sat første gang. Og ikke det som SetServo sætter den til. Hvad er det jeg gør forkert?
Avatar billede ksoren Nybegynder
22. august 2009 - 22:36 #1
Det kommer vel ret meget an på om, hvorfor og hvornår SetServol bliver kaldt og med hvad i forhold til din Update_Tick.
Avatar billede blod_1 Nybegynder
22. august 2009 - 22:47 #2
SetServo bliver kaldt hver gang der kommer en kommando ind som fortæller hvad der skal flyttes, og hvor meget. SetServo får det så behandlet, og sendt ud til Serial porten.

Timeren som tjekker den int, er sat til 1000

efter at SetServo har udført en handling, retunerer den dette

return "Channel: " + channel + nl + "Speed: " + ramp + speedTemp + nl + "Position: " + channel00 + positTemp;

Hvor nl er linieskift. Der retunerer den channel00 rigtigt nok.
Avatar billede Syska Mester
22. august 2009 - 22:49 #3
Avatar billede Syska Mester
22. august 2009 - 22:57 #4
Brug:
System.Environment.NewLine til din newline ...
Avatar billede blod_1 Nybegynder
22. august 2009 - 23:04 #5
Hvor der bliver kaldt fra

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SamplePlugin;
using System.IO.Ports;
using System.IO;
using System.Net;
using ServoController;

namespace SamplePlugin
{
    public partial class SamplePluginForm : Form
    {
        ServoControl sc = new ServoControl(); //Set instance for the ServoControl class

        public SamplePluginForm(bool haveLicense, string owner)
        {
            InitializeComponent();
        }


        private void channelsUpdate_Tick(object sender, EventArgs e)
        {
            progressBar00.Value = sc.channel00;
        }
    }
}


Det som bliver kaldt

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.IO;
using ParallaxPlugin;

namespace ServoController
{
    public class ServoControl
    {
        //Positions of servos stored here
        public int channel00 = 750;

        public string SetServo(int channel, int ramp, int position, string function) //Position between 280 and 1170
        {
            string nl = System.Environment.NewLine;
            if (channel == 0)
            {
                channel00 = position;
            }
            return "Channel: " + channel + nl + "Speed: " + ramp + speedTemp + nl + "Position: " + channel00 + positTemp;
        }
    }
}
Avatar billede ksoren Nybegynder
22. august 2009 - 23:18 #6
Men hvor kalder du SetServo?

buzzzz mistænker dig for, at du kalder metoden på et andet objekt end det i din SamplePluginForm.
Avatar billede Syska Mester
22. august 2009 - 23:22 #7
præcis som ksoren2 skriver :-)

Næsten det eneste tænkelige der sker ... og da jeg hjalp dig i går, kunne jeg forstå på dig at du var ny ... derfor jeg næsten er sikker på at du 2 steder i dit program opretter en instance af din klasser ... altså:

Servo s1 = new Servo();
Servo s2 = new Servo();

s1.SetServo(100);

s2.GetServer();

s2 indeholde stadig default værdien, men s1 indeholder 100

Men til sådan get/set operationer burde du kigger på properties i .NET

// ouT
Avatar billede blod_1 Nybegynder
23. august 2009 - 00:36 #8
hmm ja, sådan har jeg gjort, men jeg kalder den ene sc2 og den anden sc...

Har haft kigget på get/set og kunne ikke få det til rigtigt at gøre noget som helst... jeg må prøve igen igen
Avatar billede Syska Mester
23. august 2009 - 00:46 #9
Ja, men det er netop problemet hvis du gør sådan ... så er det jo ikke samme data du retter i ...

Det er jo en helt anden instance ...

Se klassen som blueprint ... til hvordan et object skal laves.

En instance så selve klassen.

Som eksempel. Audi sælger jo mange biler lavet efter samme blueprint, men folk kører jo ikke rundt i den samme bil? :-)

// ouT
Avatar billede bitmatic Nybegynder
23. august 2009 - 01:16 #10
prøv at gøre variablen static....

public static int channel00 = 750;
Avatar billede blod_1 Nybegynder
23. august 2009 - 01:21 #11
http://www.csharp-station.com/Tutorials/Lesson10.aspx

Har fundet dette, det må være den 10-2 Accessing Class Fields With Properties

Men jeg forstår ikke hvordan det på nogen måde skulle passe ind.

Så skal jeg for hver værdi t channel/ramp/position/function oprette en private og en public? Men så er det hele jo også i den forkerte fil?
Kan ikke få det til at give nogen mening. :(
Avatar billede Syska Mester
23. august 2009 - 01:28 #12
Static vil nok løse problemet som bitmatic skriver.

Men ... post nu hele dit program, vi sidder og gætter indtil vi ser _ALT_ der har med din ServoControl at gøre ...

specielt der hvor du kalder: SetServo og "new ServoControl()"

// ouT
Avatar billede blod_1 Nybegynder
23. august 2009 - 02:04 #13
Ændre den til static gav et brugbart resultat :)

Dog bruger jeg stadig nogle af mine egne funktioner, så må jeg finde ud af hvordan det ellers kan gøres, og så kan det komme med i næste version :)

Smider i begge et svar?
Avatar billede Syska Mester
23. august 2009 - 02:09 #14
Hvis det virker med static ... så er det fordi det ikke er samme object du arbejder med i dit program, men har oprettet 2 instances af den samme klasse ... som vi har sagt fra start.

Hvis du vil have løsning på hvordan du kan få det til at virke uden static skal du enten poste din kode eller sørge for at det er den samme instance du arbejde med og ikke hele tiden opretter en ny.

Hvis du kommer ud i et multithread miljø, er det ikke smart at bruge static og tror det generelt set er bad practice at gemme ting i static variabler.

Men hvis det virker så er det jo godt. Men vil dog anbefale dig at arbejde på samme object ... for din egen skyld ... debug er noget rod mange static variabler.

// ouT
Avatar billede Syska Mester
23. august 2009 - 02:09 #15
og svar
Avatar billede bitmatic Nybegynder
23. august 2009 - 09:56 #16
Den helt rigtige måde at gøre det på er nok noget med et Singleton pattern.

Det kunne du jo prøve at kigge på hvis du en dag vil gøre programmet helt lækkert :)
Avatar billede windcape Praktikant
25. august 2009 - 17:36 #17
Lidt ide til pænere kode:

return "Channel: {0}\nSpeed: {1}\nPosition: {2}", channel, (ramp + speedTemp), (channel00 + positTemp));


> Den helt rigtige måde at gøre det på er nok noget med et Singleton pattern.

Singleton er yderst yderst sjældent den "helt rigtige" måde at løse problemer på!
Avatar billede windcape Praktikant
25. august 2009 - 17:36 #18
Dette her kode jeg ville have skrevet:

return string.format("Channel: {0}\nSpeed: {1}\nPosition: {2}",
      channel, (ramp + speedTemp), (channel00 + positTemp)
);
Avatar billede windcape Praktikant
25. august 2009 - 17:44 #19
Umidbart ser en løsning med Observer Pattern ud som den rigtige løsning.
Avatar billede windcape Praktikant
25. august 2009 - 17:52 #20
Eksempel:

Hver gang ServoControl.Channel00 ændres, bliver progress-baren opdateret. Super nemt, og enkelt.

[code]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace E
{
    class ServoControl : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int _channel00;
       
        public int Channel00
        { 
            get { return _channel00; }
            set
            {
                if(value != _channel00)
                {
                    _channel00 = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("Channel00"));
                }
            }
        }
       
        public string SetServo(int channel, int ramp, int position, string function)
        {
            if(channel == 0)
            {
                Channel00 = position;
            }
           
            return "";
        }
    }   
       
    public partial class Form1 : Form
    {
        private ServoControl sc = new ServoControl();
   
        public Form1()
        {
            InitializeComponent();

            sc.PropertyChanged += new PropertyChangedEventHandler(sc_PropertyChanged);
           
            sc.Channel00 = 1;
            sc.Channel00 = 2;
            sc.Channel00 = 3;
        }

        void sc_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            progressBar1.Value = sc.Channel00;
        }
    }
}
[/code]
Avatar billede windcape Praktikant
25. august 2009 - 17:53 #21
Og eksperten hader kode poster *sigh*


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace E
{
    class ServoControl : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int _channel00;
       
        public int Channel00
        { 
            get { return _channel00; }
            set
            {
                if(value != _channel00)
                {
                    _channel00 = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("Channel00"));
                }
            }
        }
       
        public string SetServo(int channel, int ramp, int position, string function)
        {
            if(channel == 0)
            {
                Channel00 = position;
            }
           
            return "";
        }
    }   
       
    public partial class Form1 : Form
    {
        private ServoControl sc = new ServoControl();
   
        public Form1()
        {
            InitializeComponent();

            sc.PropertyChanged += new PropertyChangedEventHandler(sc_PropertyChanged);
           
            sc.Channel00 = 1;
            sc.Channel00 = 2;
            sc.Channel00 = 3;
        }

        void sc_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            progressBar1.Value = sc.Channel00;
        }
    }
}
Avatar billede bitmatic Nybegynder
25. august 2009 - 22:09 #23
--> "Singleton er yderst yderst sjældent den "helt rigtige" måde at løse problemer på!"

Sådan som jeg har forstået koden/hardware'en (uden egentlig at have set ret meget af den), så skal ServoControl altid pege på de samme servoer, igennem den samme serielport.

I den situation er Singleton pattern den "helt rigtige" måde at gøre det på.
Avatar billede blod_1 Nybegynder
25. august 2009 - 23:03 #24
Lige en lille opfølgning fra min side... Jeg har ikke glemt denne tråd, jeg kæmper lige lidt før jeg helt vil afslutte dette :)
Avatar billede windcape Praktikant
26. august 2009 - 08:30 #25
> I den situation er Singleton pattern den "helt rigtige" måde at gøre det på.

Ikke når han ikke har flere instanser? Og hvis man bare vil skrive en række statiske metoder kan man jo bare lave en statisk klasse.

Umidbart giver en servo-controller per server jo fint mening? Men selvom man har flere, så er server-controlleren jo en "observer" som jeg ser det, derfor vil en løsning med Observer være bedre end noget roderi i singleton.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester