Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Implementing a list of abstract objects...

Implementing a list of abstract objects...

Scheduled Pinned Locked Moved C#
helphardwaretoolsannouncement
9 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    faheemnadeem
    wrote on last edited by
    #1

    Hi. I have a problem which i am stuck in badly. Scenario: I have a abstract class named "VisaOscilloscope" defining some abstract methods and properties, which some driver utility classes inherit and implement the actual external hardware driver functionality.e.g. i am giving a shorter version of the class below.

    public abstract class VisaOscilloscope : Oscilloscope
    {
    [Category("IviScopeBase Capability Group")]
    [DefaultValueAttribute(0)]
    [DescriptionAttribute("Specifies the location of the center of the range that the Vertical Range attribute specifies. The value is with respect to ground and is in volts")]
    public abstract double VerticalOffset { get; set; }

        \[Category("IviScopeBase Capability Group")\]
        \[DefaultValueAttribute(0)\]
        \[DescriptionAttribute("Specifies the absolute value of the full-scale input range for a channel. The units are volts")\]
        public abstract double VerticalRange { get; set; }
    
        \[Category("IviScopeProbeAutoSense Extension Group")\]
        \[DefaultValueAttribute(false)\]
        \[DescriptionAttribute("If this attribute is True, the driver configures the oscilloscope to sense the attenuation of the probe automatically. If this attribute is False, the driver disables the automatic probe sense and configures the oscilloscope to use the value of the Probe Attenuation attribute")\]
        public abstract bool ProbeAttenuationAuto { get; set; }
    
    
        public abstract void init();
        
        public abstract void activate();
        
        public abstract void acquire();
        
        public abstract float\[\] collect();
        
        public abstract void close();
    

    Now a utility class that has to inherit from this base class and implement the properties and methods by connecting to a pre-written driver. e.g.

    class TK\_TDS1012B : VisaOscilloscope
    {
    

    public override double VerticalOffset
    {
    get
    {
    return myTk.GetDouble(tktds1k2kProperties.VerticalOffset);
    }
    set
    {
    throw new NotImplementedException();
    }
    }

        public override double VerticalRange
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    
        public override bool ProbeAttenuationAuto
    
    P 1 Reply Last reply
    0
    • F faheemnadeem

      Hi. I have a problem which i am stuck in badly. Scenario: I have a abstract class named "VisaOscilloscope" defining some abstract methods and properties, which some driver utility classes inherit and implement the actual external hardware driver functionality.e.g. i am giving a shorter version of the class below.

      public abstract class VisaOscilloscope : Oscilloscope
      {
      [Category("IviScopeBase Capability Group")]
      [DefaultValueAttribute(0)]
      [DescriptionAttribute("Specifies the location of the center of the range that the Vertical Range attribute specifies. The value is with respect to ground and is in volts")]
      public abstract double VerticalOffset { get; set; }

          \[Category("IviScopeBase Capability Group")\]
          \[DefaultValueAttribute(0)\]
          \[DescriptionAttribute("Specifies the absolute value of the full-scale input range for a channel. The units are volts")\]
          public abstract double VerticalRange { get; set; }
      
          \[Category("IviScopeProbeAutoSense Extension Group")\]
          \[DefaultValueAttribute(false)\]
          \[DescriptionAttribute("If this attribute is True, the driver configures the oscilloscope to sense the attenuation of the probe automatically. If this attribute is False, the driver disables the automatic probe sense and configures the oscilloscope to use the value of the Probe Attenuation attribute")\]
          public abstract bool ProbeAttenuationAuto { get; set; }
      
      
          public abstract void init();
          
          public abstract void activate();
          
          public abstract void acquire();
          
          public abstract float\[\] collect();
          
          public abstract void close();
      

      Now a utility class that has to inherit from this base class and implement the properties and methods by connecting to a pre-written driver. e.g.

      class TK\_TDS1012B : VisaOscilloscope
      {
      

      public override double VerticalOffset
      {
      get
      {
      return myTk.GetDouble(tktds1k2kProperties.VerticalOffset);
      }
      set
      {
      throw new NotImplementedException();
      }
      }

          public override double VerticalRange
          {
              get
              {
                  throw new NotImplementedException();
              }
              set
              {
                  throw new NotImplementedException();
              }
          }
      
          public override bool ProbeAttenuationAuto
      
      P Offline
      P Offline
      Philippe Mori
      wrote on last edited by
      #2

      You need one abstration for an oscilloscope and another one for a channel. Then an oscilloscope would have an array (or a List<>, a Dictionary<>) of channels as one of its property.

      Philippe Mori

      F 1 Reply Last reply
      0
      • P Philippe Mori

        You need one abstration for an oscilloscope and another one for a channel. Then an oscilloscope would have an array (or a List<>, a Dictionary<>) of channels as one of its property.

        Philippe Mori

        F Offline
        F Offline
        faheemnadeem
        wrote on last edited by
        #3

        hi, thanks for the reply... The problem is i need to implement the properties related to the channels in the inherited utility class. e.g. if i try your approach... which i already did... i made another abstract class and moved all the channel related properties to that class. e.g.

        public abstract class Channel
        {
        [Category("IviScopeBase Capability Group")]
        [DefaultValueAttribute(false)]
        [DescriptionAttribute("If set to True, the oscilloscope acquires a waveform for the channel. If set to False, the oscilloscope does not acquire a waveform for the channel")]
        public abstract bool ChannelEnabled { get; set; }

            \[Category("IviScopeBase Capability Group")\]
            \[DefaultValueAttribute(false)\]
            \[DescriptionAttribute("Specifies whether channel is inverted or not")\]
            public abstract bool ChannelInverted { get; set; }
        
            \[Category("IviScopeBase Capability Group")\]
            \[DefaultValueAttribute(0)\]
            \[DescriptionAttribute("Returns the physical repeated capability identifier defined by the specific driver for the channel that corresponds to the one-based index that the user specifies.  If the driver defines a qualified channel name, this property returns the qualified name")\]
            public abstract double ChannelName { get; }
        
            \[Category("IviScopeBase Capability Group")\]
            \[DefaultValueAttribute(0)\]
            \[DescriptionAttribute("Specifies the input impedance for the channel in Ohms. Common values are 50.0, 75.0, and 1,000,000.0")\]
            public abstract double InputImpedance { get; set; }
        
            \[Category("IviScopeBase Capability Group")\]
            \[DefaultValueAttribute(0)\]
            \[DescriptionAttribute("Specifies the maximum frequency for the input signal you want the instrument to accommodate without attenuating it by more than 3dB")\]
            public abstract double MaximumInputFrequency { get; set; }
        
            \[Category("IviScopeBase Capability Group")\]
            \[DefaultValueAttribute(0)\]
            \[DescriptionAttribute("Specifies the scaling factor by which the probe the end-user attaches to the channel attenuates the input.  For example, for a 10:1 probe, the end-user sets this attribute to 10.0")\]
            public abstract double ProbeAttenuation { get; set; }
        
            \[Category("IviScopeBase Capability Group")\]
            \[DefaultValueAttribute(0)\]
            \[DescriptionAttribute("Specifies how the oscilloscope couples the input signal for the channel")\]
            public abstract VerticalCou
        
        P 1 Reply Last reply
        0
        • F faheemnadeem

          hi, thanks for the reply... The problem is i need to implement the properties related to the channels in the inherited utility class. e.g. if i try your approach... which i already did... i made another abstract class and moved all the channel related properties to that class. e.g.

          public abstract class Channel
          {
          [Category("IviScopeBase Capability Group")]
          [DefaultValueAttribute(false)]
          [DescriptionAttribute("If set to True, the oscilloscope acquires a waveform for the channel. If set to False, the oscilloscope does not acquire a waveform for the channel")]
          public abstract bool ChannelEnabled { get; set; }

              \[Category("IviScopeBase Capability Group")\]
              \[DefaultValueAttribute(false)\]
              \[DescriptionAttribute("Specifies whether channel is inverted or not")\]
              public abstract bool ChannelInverted { get; set; }
          
              \[Category("IviScopeBase Capability Group")\]
              \[DefaultValueAttribute(0)\]
              \[DescriptionAttribute("Returns the physical repeated capability identifier defined by the specific driver for the channel that corresponds to the one-based index that the user specifies.  If the driver defines a qualified channel name, this property returns the qualified name")\]
              public abstract double ChannelName { get; }
          
              \[Category("IviScopeBase Capability Group")\]
              \[DefaultValueAttribute(0)\]
              \[DescriptionAttribute("Specifies the input impedance for the channel in Ohms. Common values are 50.0, 75.0, and 1,000,000.0")\]
              public abstract double InputImpedance { get; set; }
          
              \[Category("IviScopeBase Capability Group")\]
              \[DefaultValueAttribute(0)\]
              \[DescriptionAttribute("Specifies the maximum frequency for the input signal you want the instrument to accommodate without attenuating it by more than 3dB")\]
              public abstract double MaximumInputFrequency { get; set; }
          
              \[Category("IviScopeBase Capability Group")\]
              \[DefaultValueAttribute(0)\]
              \[DescriptionAttribute("Specifies the scaling factor by which the probe the end-user attaches to the channel attenuates the input.  For example, for a 10:1 probe, the end-user sets this attribute to 10.0")\]
              public abstract double ProbeAttenuation { get; set; }
          
              \[Category("IviScopeBase Capability Group")\]
              \[DefaultValueAttribute(0)\]
              \[DescriptionAttribute("Specifies how the oscilloscope couples the input signal for the channel")\]
              public abstract VerticalCou
          
          P Offline
          P Offline
          Philippe Mori
          wrote on last edited by
          #4

          Well the concrete channel class might have a reference to the containing scope if this is usefll for the implementation of the properties. This might be the case if the concrete oscilloscope class has functions like EnableChannel(int channelId, bool enabled). One way would be that each oscilloscope fill its channel list with appropriate channels.

          void InitChannels()
          {
          List newChannels = new List

          int channelId = 1;
          newChannels.Add(new AnalogChannel(this, channelId));

          ++channelId;
          newChannels.Add(new AnalogChannel(this, channelId));

          int digitalChannels = 16;
          for (int i = 0; i != digitalChannels; ++i)
          {
          ++channelId;
          newChannels.Add(new DigitalChannel(this, channelId);
          }

          ++channelId;
          newChannels.Add(new ClockChannel(this, channelId);

          ++channelId;
          newChannels.Add(new TriggerChannel(this, channelId);

          // Update oscilloscope channels...
          Channels = newChannels;
          }

          Philippe Mori

          F 1 Reply Last reply
          0
          • P Philippe Mori

            Well the concrete channel class might have a reference to the containing scope if this is usefll for the implementation of the properties. This might be the case if the concrete oscilloscope class has functions like EnableChannel(int channelId, bool enabled). One way would be that each oscilloscope fill its channel list with appropriate channels.

            void InitChannels()
            {
            List newChannels = new List

            int channelId = 1;
            newChannels.Add(new AnalogChannel(this, channelId));

            ++channelId;
            newChannels.Add(new AnalogChannel(this, channelId));

            int digitalChannels = 16;
            for (int i = 0; i != digitalChannels; ++i)
            {
            ++channelId;
            newChannels.Add(new DigitalChannel(this, channelId);
            }

            ++channelId;
            newChannels.Add(new ClockChannel(this, channelId);

            ++channelId;
            newChannels.Add(new TriggerChannel(this, channelId);

            // Update oscilloscope channels...
            Channels = newChannels;
            }

            Philippe Mori

            F Offline
            F Offline
            faheemnadeem
            wrote on last edited by
            #5

            Yes you are right again... What i have done till now is initialize the channel list in the utility class inheriting from visaoscilloscope. While implementing the 'init' method i populate the list with channels and their respective properties by connecting to the respective oscilloscope driver and getting real-time value of that property for that particular channel and correspondingly update the list. This only happens once i call the init method the first time. The problem which i am trying to figure out is they way i have implemented the base oscilloscope properties is that they are connected to the driver itself in the gettter setters, so they give me the current realtime value of the oscilloscope attribute when they are called from let say my GUI class. e.g. if i ask a visaoscilloscope for its ID. which is a general property has to be implemented by each oscilloscope. So i do from my gui class. assume this scope object points to a particular utility/driver/scope

            visaoscilloscope myscope = new visaoscilloscope();
            string ID = myscope.ID;

            the id field which is abstract in visaoscilloscope is implemented in the inherited utility class (because there are different ways of getting an ID for each driver and i have to connect a driver class to it also) so in the ID implementation, i just do this.

            public override string ID
            {
            get { return myTk.GetString(tktds1k2kProperties.IdQueryResponse); }
            }

            Therefore it always gives me real-time response from oscilloscope. What i want is also realtime response for my channel properties. if i implement the current scenario u suggested the fields are only updated once i call the init method. which have to be called only once during the initialization phase. If you understood my point i would be really thankful to hear a solution... if u want i can send u the classes... i know it is a simple enough problem. but this is something i have never tried and i am particularly new to this... Really thankful for the help u have given my thus far...

            P 1 Reply Last reply
            0
            • F faheemnadeem

              Yes you are right again... What i have done till now is initialize the channel list in the utility class inheriting from visaoscilloscope. While implementing the 'init' method i populate the list with channels and their respective properties by connecting to the respective oscilloscope driver and getting real-time value of that property for that particular channel and correspondingly update the list. This only happens once i call the init method the first time. The problem which i am trying to figure out is they way i have implemented the base oscilloscope properties is that they are connected to the driver itself in the gettter setters, so they give me the current realtime value of the oscilloscope attribute when they are called from let say my GUI class. e.g. if i ask a visaoscilloscope for its ID. which is a general property has to be implemented by each oscilloscope. So i do from my gui class. assume this scope object points to a particular utility/driver/scope

              visaoscilloscope myscope = new visaoscilloscope();
              string ID = myscope.ID;

              the id field which is abstract in visaoscilloscope is implemented in the inherited utility class (because there are different ways of getting an ID for each driver and i have to connect a driver class to it also) so in the ID implementation, i just do this.

              public override string ID
              {
              get { return myTk.GetString(tktds1k2kProperties.IdQueryResponse); }
              }

              Therefore it always gives me real-time response from oscilloscope. What i want is also realtime response for my channel properties. if i implement the current scenario u suggested the fields are only updated once i call the init method. which have to be called only once during the initialization phase. If you understood my point i would be really thankful to hear a solution... if u want i can send u the classes... i know it is a simple enough problem. but this is something i have never tried and i am particularly new to this... Really thankful for the help u have given my thus far...

              P Offline
              P Offline
              Philippe Mori
              wrote on last edited by
              #6

              For each property you might decided where it is best to have the actual implementation. I'm not sure how your data get updated and how it used. You can uses events if you need to know when data is changed. In pratice, it might be simpler to detect changes at the oscilloscope level as you would need to connect to a single event that would contain information on the change. Thus it might be simpler if the actual implementation is in the scope (except if channel are mainly used independtly --- that is one view per channel --- in that case, events could be on each channel). It is possible to have both also. Assuming that a TkChannel can be used only with a TkOscilloscope, they can easily share information or talk together either though functions or events.

              Philippe Mori

              F 1 Reply Last reply
              0
              • P Philippe Mori

                For each property you might decided where it is best to have the actual implementation. I'm not sure how your data get updated and how it used. You can uses events if you need to know when data is changed. In pratice, it might be simpler to detect changes at the oscilloscope level as you would need to connect to a single event that would contain information on the change. Thus it might be simpler if the actual implementation is in the scope (except if channel are mainly used independtly --- that is one view per channel --- in that case, events could be on each channel). It is possible to have both also. Assuming that a TkChannel can be used only with a TkOscilloscope, they can easily share information or talk together either though functions or events.

                Philippe Mori

                F Offline
                F Offline
                faheemnadeem
                wrote on last edited by
                #7

                I think so its better if i give u the class implementations. a quick look will clarify u everything... What i intend to do in a bigger picture is implement a experiment which uses two kinds of hardware an oscilloscope and an encryption board. i intend to measure power waves from the fpga board when an encryption is being done, collect its waveform and store it some where. this single step is called collecting a trace. i intend to do it almost a million times in a fast manner. and record a million waveforms acquired from oscilloscope somewhere. The have made wrappers for the original oscilloscope driver written in c++ so they are compatible with c#. the drivers are all written, they specify to IVI standard and all the methods are implemented in a form of a class. The class hierarchy i intend to implement for the experiment is: IOscilloscope <---- Oscilloscope <----- Visa Oscilloscope <------ (TkTDS1012B , DSO1024) The last classes e.g. tktds1012B connects to a driver class (e.g. tk1k2kDriver and connects to required methods it requires to get data from oscilloscope. I am providing the links to these classes: http://www.mediafire.com/?p3hzzcn2o45qucv Kindly if u have some time, then have a look at it... I just want a way to implement the properties for channel class they way i implement visaoscilloscope properties in inherited classes... Thank you for your help thus far...

                P 1 Reply Last reply
                0
                • F faheemnadeem

                  I think so its better if i give u the class implementations. a quick look will clarify u everything... What i intend to do in a bigger picture is implement a experiment which uses two kinds of hardware an oscilloscope and an encryption board. i intend to measure power waves from the fpga board when an encryption is being done, collect its waveform and store it some where. this single step is called collecting a trace. i intend to do it almost a million times in a fast manner. and record a million waveforms acquired from oscilloscope somewhere. The have made wrappers for the original oscilloscope driver written in c++ so they are compatible with c#. the drivers are all written, they specify to IVI standard and all the methods are implemented in a form of a class. The class hierarchy i intend to implement for the experiment is: IOscilloscope <---- Oscilloscope <----- Visa Oscilloscope <------ (TkTDS1012B , DSO1024) The last classes e.g. tktds1012B connects to a driver class (e.g. tk1k2kDriver and connects to required methods it requires to get data from oscilloscope. I am providing the links to these classes: http://www.mediafire.com/?p3hzzcn2o45qucv Kindly if u have some time, then have a look at it... I just want a way to implement the properties for channel class they way i implement visaoscilloscope properties in inherited classes... Thank you for your help thus far...

                  P Offline
                  P Offline
                  Philippe Mori
                  wrote on last edited by
                  #8

                  I haven't look at your code. I don't even think I have a program to open RAR file... Typically, I would think that you would also have: IChannel <----- Channel <---- VisaChannel <---- .... If the creation of the channel is done by the concrete oscilloscope, you can provide the concrete oscilloscope to the channel and from there you can do whatever you want. Handle it there, handle in parent channel class or handle it in the oscilloscope class (ideally through IOscilloscope but if you need you can also uses concrete oscilloscope classes). The exact implementation depedds a lot on how much the implementation of channels are similar between oscilloscopes and also how existing code is implemented. Assuming that there is one driver class object for one oscilloscope that give access to channel and scope functions, then it would probably make sense that each concrete channel class would simple call the appropriate function in the corresponding scope. Assuming that your channel do have an ID, you might have an interface IOscilloscopeForChannels that would be implemented by the oscilloscope for use by channels.

                  interface IOscilloscopeForChannels
                  {
                  bool IsChannelEnabled(string channelId);
                  //...
                  }

                  Then a property from the channel simply call that method in the oscilloscope providing any passed argument and adding its owns ID. You would then be able to use a channel like this:

                  var oscilloscope1 = GetTheOscilloscope();

                  /// Get a reference to the channel we want to uses
                  var channel3 = oscilloscope1.Channels["ch3"]; // Channels could be a dictionary

                  // Uses that channel in code.
                  // The channel might forward the call to the oscilloscope class.
                  channel3.IsEnabled = true;
                  AddToView(channel3.CurrentValue);
                  channel3.IsEnable = false;

                  Philippe Mori

                  F 1 Reply Last reply
                  0
                  • P Philippe Mori

                    I haven't look at your code. I don't even think I have a program to open RAR file... Typically, I would think that you would also have: IChannel <----- Channel <---- VisaChannel <---- .... If the creation of the channel is done by the concrete oscilloscope, you can provide the concrete oscilloscope to the channel and from there you can do whatever you want. Handle it there, handle in parent channel class or handle it in the oscilloscope class (ideally through IOscilloscope but if you need you can also uses concrete oscilloscope classes). The exact implementation depedds a lot on how much the implementation of channels are similar between oscilloscopes and also how existing code is implemented. Assuming that there is one driver class object for one oscilloscope that give access to channel and scope functions, then it would probably make sense that each concrete channel class would simple call the appropriate function in the corresponding scope. Assuming that your channel do have an ID, you might have an interface IOscilloscopeForChannels that would be implemented by the oscilloscope for use by channels.

                    interface IOscilloscopeForChannels
                    {
                    bool IsChannelEnabled(string channelId);
                    //...
                    }

                    Then a property from the channel simply call that method in the oscilloscope providing any passed argument and adding its owns ID. You would then be able to use a channel like this:

                    var oscilloscope1 = GetTheOscilloscope();

                    /// Get a reference to the channel we want to uses
                    var channel3 = oscilloscope1.Channels["ch3"]; // Channels could be a dictionary

                    // Uses that channel in code.
                    // The channel might forward the call to the oscilloscope class.
                    channel3.IsEnabled = true;
                    AddToView(channel3.CurrentValue);
                    channel3.IsEnable = false;

                    Philippe Mori

                    F Offline
                    F Offline
                    faheemnadeem
                    wrote on last edited by
                    #9

                    Thank you for your help. Really appreciated... I will have a look at this approach and implement it. Thanks again!!!

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups